Re: [RFC PATCH 0/3] Introduce support for creating IIO devices via configfs

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On 20/04/16 16:45, Daniel Baluta wrote:
> For testing purposes is nice to have a quick way of creating IIO devices.
> This patch series introduces support for creating IIO devices via configs
> (patch 1), allowing users to register "device types". For the moment we
> support "dummy" device type (patch 2).
> 
> This is just a RFC in order to see if the interface is acceptable. We also
> need a way to create IIO devices with configurable number of channels.
> 
> Patch 3 introduces configfs entries documentation for easier review.
> 
> Daniel Baluta (3):
>   iio: Add support for creating IIO devices via configfs
>   iio: dummy: Convert IIO dummy to configfs
>   Documentation: iio: Add IIO software devices docs
> 
>  Documentation/ABI/testing/configfs-iio |  13 +++
>  drivers/iio/Kconfig                    |   9 ++
>  drivers/iio/Makefile                   |   1 +
>  drivers/iio/dummy/iio_simple_dummy.c   |  98 ++++++------------
>  drivers/iio/industrialio-sw-device.c   | 181 +++++++++++++++++++++++++++++++++
>  include/linux/iio/sw_device.h          |  70 +++++++++++++
>  6 files changed, 307 insertions(+), 65 deletions(-)
>  create mode 100644 drivers/iio/industrialio-sw-device.c
>  create mode 100644 include/linux/iio/sw_device.h
> 
Sorry, I was a muppet and delete patch one due to a misstap on my phone...
Anyhow, pasting it in here to review...

> This is similar with support for creating triggers via configfs.
> Devices will be hosted under:
> 	* /config/iio/devices
> 
> We allow users to register "device types" under:
> 	* /config/iio/devices/<device_types>/
> 
> Signed-off-by: Daniel Baluta <daniel.baluta@xxxxxxxxx>
As you observed, there is room in here to share some code with the sw-trigger
support.  Looks like we are going to have an iio-configfs helper library
or perhaps just move them into the industrialio-configfs module...

However, I'm not sure it's actually a good idea.  Seems to me that the amount
of fiddly indirection needed would outway the advantages in reduced code
replication.

Other than a few nitpicks this looks good to me - though that's not surprising
as it's a find and replace job on the trigger version!

Jonathan
> ---
>  drivers/iio/Kconfig                  |   9 ++
>  drivers/iio/Makefile                 |   1 +
>  drivers/iio/industrialio-sw-device.c | 181 +++++++++++++++++++++++++++++++++++
>  include/linux/iio/sw_device.h        |  70 ++++++++++++++
>  4 files changed, 261 insertions(+)
>  create mode 100644 drivers/iio/industrialio-sw-device.c
>  create mode 100644 include/linux/iio/sw_device.h
> 
> diff --git a/drivers/iio/Kconfig b/drivers/iio/Kconfig
> index 505e921..77711a3 100644
> --- a/drivers/iio/Kconfig
> +++ b/drivers/iio/Kconfig
> @@ -46,6 +46,15 @@ config IIO_CONSUMERS_PER_TRIGGER
>  	This value controls the maximum number of consumers that a
>  	given trigger may handle. Default is 2.
>  
> +config IIO_SW_DEVICE
> +	tristate "Enable software IIO device support"
> +	select IIO_CONFIGFS
> +	help
> +	 Provides IIO core support for software device. A software
> +	 device can be created via configfs or directly by a driver
> +	 using the API provided.
> +
One blank line too many here...
> +
>  config IIO_SW_TRIGGER
>  	tristate "Enable software triggers support"
>  	select IIO_CONFIGFS
> diff --git a/drivers/iio/Makefile b/drivers/iio/Makefile
> index 20f6490..87e4c43 100644
> --- a/drivers/iio/Makefile
> +++ b/drivers/iio/Makefile
> @@ -8,6 +8,7 @@ industrialio-$(CONFIG_IIO_BUFFER) += industrialio-buffer.o
>  industrialio-$(CONFIG_IIO_TRIGGER) += industrialio-trigger.o
>  
>  obj-$(CONFIG_IIO_CONFIGFS) += industrialio-configfs.o
> +obj-$(CONFIG_IIO_SW_DEVICE) += industrialio-sw-device.o
>  obj-$(CONFIG_IIO_SW_TRIGGER) += industrialio-sw-trigger.o
>  obj-$(CONFIG_IIO_TRIGGERED_EVENT) += industrialio-triggered-event.o
>  
> diff --git a/drivers/iio/industrialio-sw-device.c b/drivers/iio/industrialio-sw-device.c
> new file mode 100644
> index 0000000..243aaf4
> --- /dev/null
> +++ b/drivers/iio/industrialio-sw-device.c
> @@ -0,0 +1,181 @@
> +/*
> + * The Industrial I/O core, software IIO devices functions
> + *
> + * Copyright (c) 2015 Intel Corporation
I think you can reasonably claim 2016 - but up to you.
> + *
> + * This program is free software; you can redistribute it and/or modify it
> + * under the terms of the GNU General Public License version 2 as published by
> + * the Free Software Foundation.
> + */
> +
> +#include <linux/module.h>
> +#include <linux/init.h>
> +#include <linux/kmod.h>
> +#include <linux/list.h>
> +#include <linux/slab.h>
> +
> +#include <linux/iio/sw_device.h>
> +#include <linux/iio/configfs.h>
> +#include <linux/configfs.h>
> +
> +static struct config_group *iio_devices_group;
> +static struct config_item_type iio_device_type_group_type;
> +
> +static struct config_item_type iio_devices_group_type = {
> +	.ct_owner = THIS_MODULE,
> +};
> +
> +static LIST_HEAD(iio_device_types_list);
> +static DEFINE_MUTEX(iio_device_types_lock);
> +
> +static
> +struct iio_sw_device_type *__iio_find_sw_device_type(const char *name,
> +						     unsigned len)
> +{
> +	struct iio_sw_device_type *d = NULL, *iter;
> +
> +	list_for_each_entry(iter, &iio_device_types_list, list)
> +		if (!strcmp(iter->name, name)) {
> +			d = iter;
> +			break;
> +		}
> +
> +	return d;
> +}
> +
> +int iio_register_sw_device_type(struct iio_sw_device_type *d)
> +{
> +	struct iio_sw_device_type *iter;
> +	int ret = 0;
> +
> +	mutex_lock(&iio_device_types_lock);
> +	iter = __iio_find_sw_device_type(d->name, strlen(d->name));
> +	if (iter)
> +		ret = -EBUSY;
> +	else
> +		list_add_tail(&d->list, &iio_device_types_list);
> +	mutex_unlock(&iio_device_types_lock);
> +
> +	if (ret)
> +		return ret;
> +
> +	d->group = configfs_register_default_group(iio_devices_group, d->name,
> +						&iio_device_type_group_type);
> +	if (IS_ERR(d->group))
> +		ret = PTR_ERR(d->group);
> +
> +	return ret;
> +}
> +EXPORT_SYMBOL(iio_register_sw_device_type);
> +
> +void iio_unregister_sw_device_type(struct iio_sw_device_type *dt)
> +{
> +	struct iio_sw_device_type *iter;
> +
> +	mutex_lock(&iio_device_types_lock);
> +	iter = __iio_find_sw_device_type(dt->name, strlen(dt->name));
> +	if (iter)
> +		list_del(&dt->list);
> +	mutex_unlock(&iio_device_types_lock);
> +
> +	configfs_unregister_default_group(dt->group);
> +}
> +EXPORT_SYMBOL(iio_unregister_sw_device_type);
> +
> +static
> +struct iio_sw_device_type *iio_get_sw_device_type(const char *name)
> +{
> +	struct iio_sw_device_type *dt;
> +
> +	mutex_lock(&iio_device_types_lock);
> +	dt = __iio_find_sw_device_type(name, strlen(name));
> +	if (dt && !try_module_get(dt->owner))
> +		dt = NULL;
> +	mutex_unlock(&iio_device_types_lock);
> +
> +	return dt;
> +}
> +
> +struct iio_sw_device *iio_sw_device_create(const char *type, const char *name)
> +{
> +	struct iio_sw_device *d;
> +	struct iio_sw_device_type *dt;
> +
> +	dt = iio_get_sw_device_type(type);
> +	if (!dt) {
> +		pr_err("Invalid device type: %s\n", type);
> +		return ERR_PTR(-EINVAL);
> +	}
> +	d = dt->ops->probe(name);
> +	if (IS_ERR(d))
> +		goto out_module_put;
> +
> +	d->device_type = dt;
> +
> +	return d;
> +out_module_put:
> +	module_put(dt->owner);
> +	return d;
> +}
> +EXPORT_SYMBOL(iio_sw_device_create);
> +
> +void iio_sw_device_destroy(struct iio_sw_device *d)
> +{
> +	struct iio_sw_device_type *dt = d->device_type;
> +
> +	dt->ops->remove(d);
> +	module_put(dt->owner);
> +}
> +EXPORT_SYMBOL(iio_sw_device_destroy);
> +
> +static struct config_group *device_make_group(struct config_group *group,
> +					      const char *name)
> +{
> +	struct iio_sw_device *d;
> +
> +	d = iio_sw_device_create(group->cg_item.ci_name, name);
> +	if (IS_ERR(d))
> +		return ERR_CAST(d);
> +
> +	config_item_set_name(&d->group.cg_item, "%s", name);
blank line here (funilly enough yuo have one in the trigger version)
> +	return &d->group;
> +}
> +
> +static void device_drop_group(struct config_group *group,
> +			      struct config_item *item)
> +{
> +	struct iio_sw_device *d = to_iio_sw_device(item);
> +
> +	iio_sw_device_destroy(d);
> +	config_item_put(item);
> +}
> +
> +static struct configfs_group_operations device_ops = {
> +	.make_group	= &device_make_group,
> +	.drop_item	= &device_drop_group,
> +};
> +
> +static struct config_item_type iio_device_type_group_type = {
> +	.ct_group_ops = &device_ops,
> +	.ct_owner       = THIS_MODULE,
> +};
> +
> +static int __init iio_sw_device_init(void)
> +{
> +	iio_devices_group =
> +		configfs_register_default_group(&iio_configfs_subsys.su_group,
> +						"devices",
> +						&iio_devices_group_type);
> +	return PTR_ERR_OR_ZERO(iio_devices_group);
> +}
> +module_init(iio_sw_device_init);
> +
> +static void __exit iio_sw_device_exit(void)
> +{
> +	configfs_unregister_default_group(iio_devices_group);
> +}
> +module_exit(iio_sw_device_exit);
> +
> +MODULE_AUTHOR("Daniel Baluta <daniel.baluta@xxxxxxxxx>");
> +MODULE_DESCRIPTION("Industrial I/O software devices support");
> +MODULE_LICENSE("GPL v2");
> diff --git a/include/linux/iio/sw_device.h b/include/linux/iio/sw_device.h
> new file mode 100644
> index 0000000..672a9ad
> --- /dev/null
> +++ b/include/linux/iio/sw_device.h
> @@ -0,0 +1,70 @@
> +/*
> + * Industrial I/O software device interface
> + *
> + * Copyright (c) 2015 Intel Corporation
> + *
> + * This program is free software; you can redistribute it and/or modify it
> + * under the terms of the GNU General Public License version 2 as published by
> + * the Free Software Foundation.
> + */
> +
> +#ifndef __IIO_SW_DEVICE
> +#define __IIO_SW_DEVICE
> +
> +#include <linux/module.h>
> +#include <linux/device.h>
> +#include <linux/iio/iio.h>
> +#include <linux/configfs.h>
> +
> +#define module_iio_sw_device_driver(__iio_sw_device_type) \
> +	module_driver(__iio_sw_device_type, iio_register_sw_device_type, \
> +		      iio_unregister_sw_device_type)
> +
> +struct iio_sw_device_ops;
> +
> +struct iio_sw_device_type {
> +	const char *name;
> +	struct module *owner;
> +	const struct iio_sw_device_ops *ops;
> +	struct list_head list;
> +	struct config_group *group;
> +};
> +
> +struct iio_sw_device {
> +	struct iio_dev *device;
> +	struct iio_sw_device_type *device_type;
> +	struct config_group group;
> +};
> +
> +struct iio_sw_device_ops {
> +	struct iio_sw_device* (*probe)(const char *);
> +	int (*remove)(struct iio_sw_device *);
> +};
> +
> +static inline
> +struct iio_sw_device *to_iio_sw_device(struct config_item *item)
> +{
> +	return container_of(to_config_group(item), struct iio_sw_device,
> +			    group);
> +}
> +
> +int iio_register_sw_device_type(struct iio_sw_device_type *dt);
> +void iio_unregister_sw_device_type(struct iio_sw_device_type *dt);
> +
> +struct iio_sw_device *iio_sw_device_create(const char *, const char *);
> +void iio_sw_device_destroy(struct iio_sw_device *);
> +
> +int iio_sw_device_type_configfs_register(struct iio_sw_device_type *dt);
> +void iio_sw_device_type_configfs_unregister(struct iio_sw_device_type *dt);
> +
> +static inline
> +void iio_swd_group_init_type_name(struct iio_sw_device *d,
> +				  const char *name,
> +				  struct config_item_type *type)
> +{
> +#ifdef CONFIG_CONFIGFS_FS
> +	config_group_init_type_name(&d->group, name, type);
> +#endif
> +}
> +
> +#endif /* __IIO_SW_DEVICE */
> -- 
> 2.5.0
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-iio" in
> the body of a message to majordomo@xxxxxxxxxxxxxxx
> More majordomo info at  http://vger.kernel.org/majordomo-info.html


--
To unsubscribe from this list: send the line "unsubscribe linux-iio" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html



[Index of Archives]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Input]     [Linux Kernel]     [Linux SCSI]     [X.org]

  Powered by Linux