All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v9 0/5] Add initial configfs support for IIO
@ 2015-10-23 12:32 ` Daniel Baluta
  0 siblings, 0 replies; 12+ messages in thread
From: Daniel Baluta @ 2015-10-23 12:32 UTC (permalink / raw)
  To: jic23, jlbec, linux-iio, linux-fsdevel, lars, hch
  Cc: knaack.h, linux-kernel, octavian.purdila, pebolle,
	patrick.porlan, adriana.reus, constantin.musca, marten,
	daniel.baluta, cristina.opriceana, pmeerw, viro, akpm

This patchset introduces IIO software triggers, offers a way of configuring
them via configfs and adds the IIO hrtimer based interrupt source to be used
with software triggers.

The arhitecture is now split in 3 parts, to remove all IIO trigger specific
parts from IIO configfs core:

(1) IIO configfs - creates the root of the IIO configfs subsys.
(2) IIO software triggers - software trigger implementation, dynamically
	creating /config/iio/triggers group.
(3) IIO hrtimer trigger - is the first interrupt source for software triggers
        (with syfs to follow). Each trigger type can implement its own set of
        attributes.

Lockdep seems to be happy with the locking in configfs patch.

Changes since v8:
   * patch 1/5
	* dynamically allocate groups as suggested by Christoph
	* add kernel-doc documentation to the newly introduced functions
   * patch 2/5
	* better isolation, here we only create the root of the IIO configfs
	subys, and let the other modules (e.g software triggers) to create their
	group.
   * patch 3/5
	* dynamically create triggers/ group to better isolate the code
	* fixes 0-day build warnings and compilation errors.
   * patch 4/5
	* none
   * patch 5/5
	* none

Changes since v7:
   * patch 1/5
        * do not add dentry parameter for create_default_group, we can
          retrieve it from group.
        * call configfs_detach_prep before configfs_detach_group in
          configfs_unregister_group.
        * call link_group/unlink_group under su_mutex lock
        * take configfs_dirent_lock when calling configfs_dir_set_ready
  * patch 2/5
        * export iio_triggers_group, this will be later used by sw triggers
  * patch 3/5
        * make iio_sw_trigger part of industrialio core
        * fix compilation problem reported by Vladimir and Lars. Things didn't
        get well when having IIO_SW_TRIGGER enabled and IIO_CONFIGFS disabled.
        * use format string in config_item_set_name
        * make iio_unregister_sw_trigger_type return type void.
  * patch 4/5
        * none
  * patch 5/5
        * include a small trigger type sample example.

Changes since v6:
        * implemented Lars-Peter's idea (https://lkml.org/lkml/2015/5/13/302)
        to switch from /config/iio/triggers/hrtimer-instance1 to
        /config/iio/triggers/instance1.

Changes since v5: (after Lars comments)
        * the most important change is that we moved sampling_frequency attribute
        from configfs to trigger's directory in /sys.
        * couple of const added to strings
        * documentation to public API in sw_trigger.h
        * replace pr_err with WARN_ONCE in trigger_make_group to avoid spamming
        kernel log, but without leaving user clueless in case of errors.
        * we still need to decide if we get a real gain by adding min/max limits
        for sampling frequency in /config dir. Anyhow, this can be done in a later
        patch.
        * fix race in hrtimer_remove

Changes since v4:
        * patch 1/4
                - fixed "new line" nit in industrialio-sw-trigger.c
                - added license header in sw_trigger.h o
        * patch 2/4
                - none
        * patch 3/4
                - none
        * patch 4/4
                - removed "Further work" chapter in iio_configfs.txt

                - added configfs-iio file in Documentation/ABI/testing

Daniel Baluta (5):
  configfs: Allow dynamic group creation
  iio: core: Introduce IIO configfs support
  iio: core: Introduce IIO software triggers
  iio: trigger: Introduce IIO hrtimer based trigger
  iio: Documentation: Add IIO configfs documentation

 Documentation/ABI/testing/configfs-iio |  21 ++++
 Documentation/iio/iio_configfs.txt     |  93 +++++++++++++++
 drivers/iio/Kconfig                    |  16 +++
 drivers/iio/Makefile                   |   2 +
 drivers/iio/industrialio-configfs.c    |  50 ++++++++
 drivers/iio/industrialio-sw-trigger.c  | 206 +++++++++++++++++++++++++++++++++
 drivers/iio/trigger/Kconfig            |  10 ++
 drivers/iio/trigger/Makefile           |   2 +
 drivers/iio/trigger/iio-trig-hrtimer.c | 193 ++++++++++++++++++++++++++++++
 fs/configfs/dir.c                      | 102 ++++++++++++++++
 include/linux/configfs.h               |   8 ++
 include/linux/iio/sw_trigger.h         |  71 ++++++++++++
 12 files changed, 774 insertions(+)
 create mode 100644 Documentation/ABI/testing/configfs-iio
 create mode 100644 Documentation/iio/iio_configfs.txt
 create mode 100644 drivers/iio/industrialio-configfs.c
 create mode 100644 drivers/iio/industrialio-sw-trigger.c
 create mode 100644 drivers/iio/trigger/iio-trig-hrtimer.c
 create mode 100644 include/linux/iio/sw_trigger.h

-- 
1.9.1


^ permalink raw reply	[flat|nested] 12+ messages in thread

* [PATCH v9 0/5] Add initial configfs support for IIO
@ 2015-10-23 12:32 ` Daniel Baluta
  0 siblings, 0 replies; 12+ messages in thread
From: Daniel Baluta @ 2015-10-23 12:32 UTC (permalink / raw)
  To: jic23-DgEjT+Ai2ygdnm+yROfE0A, jlbec-aKy9MeLSZ9dg9hUCZPvPmw,
	linux-iio-u79uwXL29TY76Z2rM5mHXA,
	linux-fsdevel-u79uwXL29TY76Z2rM5mHXA,
	lars-Qo5EllUWu/uELgA04lAiVw, hch-jcswGhMUV9g
  Cc: knaack.h-Mmb7MZpHnFY, linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	octavian.purdila-ral2JQCrhuEAvxtiuMwx3w,
	pebolle-IWqWACnzNjzz+pZb47iToQ,
	patrick.porlan-ral2JQCrhuEAvxtiuMwx3w,
	adriana.reus-ral2JQCrhuEAvxtiuMwx3w,
	constantin.musca-ral2JQCrhuEAvxtiuMwx3w,
	marten-4zOpVvZifTgX8gGd4fc/mEEOCMrvLtNR,
	daniel.baluta-ral2JQCrhuEAvxtiuMwx3w,
	cristina.opriceana-Re5JQEeQqe8AvxtiuMwx3w,
	pmeerw-jW+XmwGofnusTnJN9+BGXg,
	viro-RmSDqhL/yNMiFSDQTTA3OLVCufUGDwFn,
	akpm-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b

This patchset introduces IIO software triggers, offers a way of configuring
them via configfs and adds the IIO hrtimer based interrupt source to be used
with software triggers.

The arhitecture is now split in 3 parts, to remove all IIO trigger specific
parts from IIO configfs core:

(1) IIO configfs - creates the root of the IIO configfs subsys.
(2) IIO software triggers - software trigger implementation, dynamically
	creating /config/iio/triggers group.
(3) IIO hrtimer trigger - is the first interrupt source for software triggers
        (with syfs to follow). Each trigger type can implement its own set of
        attributes.

Lockdep seems to be happy with the locking in configfs patch.

Changes since v8:
   * patch 1/5
	* dynamically allocate groups as suggested by Christoph
	* add kernel-doc documentation to the newly introduced functions
   * patch 2/5
	* better isolation, here we only create the root of the IIO configfs
	subys, and let the other modules (e.g software triggers) to create their
	group.
   * patch 3/5
	* dynamically create triggers/ group to better isolate the code
	* fixes 0-day build warnings and compilation errors.
   * patch 4/5
	* none
   * patch 5/5
	* none

Changes since v7:
   * patch 1/5
        * do not add dentry parameter for create_default_group, we can
          retrieve it from group.
        * call configfs_detach_prep before configfs_detach_group in
          configfs_unregister_group.
        * call link_group/unlink_group under su_mutex lock
        * take configfs_dirent_lock when calling configfs_dir_set_ready
  * patch 2/5
        * export iio_triggers_group, this will be later used by sw triggers
  * patch 3/5
        * make iio_sw_trigger part of industrialio core
        * fix compilation problem reported by Vladimir and Lars. Things didn't
        get well when having IIO_SW_TRIGGER enabled and IIO_CONFIGFS disabled.
        * use format string in config_item_set_name
        * make iio_unregister_sw_trigger_type return type void.
  * patch 4/5
        * none
  * patch 5/5
        * include a small trigger type sample example.

Changes since v6:
        * implemented Lars-Peter's idea (https://lkml.org/lkml/2015/5/13/302)
        to switch from /config/iio/triggers/hrtimer-instance1 to
        /config/iio/triggers/instance1.

Changes since v5: (after Lars comments)
        * the most important change is that we moved sampling_frequency attribute
        from configfs to trigger's directory in /sys.
        * couple of const added to strings
        * documentation to public API in sw_trigger.h
        * replace pr_err with WARN_ONCE in trigger_make_group to avoid spamming
        kernel log, but without leaving user clueless in case of errors.
        * we still need to decide if we get a real gain by adding min/max limits
        for sampling frequency in /config dir. Anyhow, this can be done in a later
        patch.
        * fix race in hrtimer_remove

Changes since v4:
        * patch 1/4
                - fixed "new line" nit in industrialio-sw-trigger.c
                - added license header in sw_trigger.h o
        * patch 2/4
                - none
        * patch 3/4
                - none
        * patch 4/4
                - removed "Further work" chapter in iio_configfs.txt

                - added configfs-iio file in Documentation/ABI/testing

Daniel Baluta (5):
  configfs: Allow dynamic group creation
  iio: core: Introduce IIO configfs support
  iio: core: Introduce IIO software triggers
  iio: trigger: Introduce IIO hrtimer based trigger
  iio: Documentation: Add IIO configfs documentation

 Documentation/ABI/testing/configfs-iio |  21 ++++
 Documentation/iio/iio_configfs.txt     |  93 +++++++++++++++
 drivers/iio/Kconfig                    |  16 +++
 drivers/iio/Makefile                   |   2 +
 drivers/iio/industrialio-configfs.c    |  50 ++++++++
 drivers/iio/industrialio-sw-trigger.c  | 206 +++++++++++++++++++++++++++++++++
 drivers/iio/trigger/Kconfig            |  10 ++
 drivers/iio/trigger/Makefile           |   2 +
 drivers/iio/trigger/iio-trig-hrtimer.c | 193 ++++++++++++++++++++++++++++++
 fs/configfs/dir.c                      | 102 ++++++++++++++++
 include/linux/configfs.h               |   8 ++
 include/linux/iio/sw_trigger.h         |  71 ++++++++++++
 12 files changed, 774 insertions(+)
 create mode 100644 Documentation/ABI/testing/configfs-iio
 create mode 100644 Documentation/iio/iio_configfs.txt
 create mode 100644 drivers/iio/industrialio-configfs.c
 create mode 100644 drivers/iio/industrialio-sw-trigger.c
 create mode 100644 drivers/iio/trigger/iio-trig-hrtimer.c
 create mode 100644 include/linux/iio/sw_trigger.h

-- 
1.9.1

^ permalink raw reply	[flat|nested] 12+ messages in thread

* [PATCH v9 1/5] configfs: Allow dynamic group creation
  2015-10-23 12:32 ` Daniel Baluta
  (?)
@ 2015-10-23 12:32 ` Daniel Baluta
  2015-10-23 12:48   ` Christoph Hellwig
  -1 siblings, 1 reply; 12+ messages in thread
From: Daniel Baluta @ 2015-10-23 12:32 UTC (permalink / raw)
  To: jic23, jlbec, linux-iio, linux-fsdevel, lars, hch
  Cc: knaack.h, linux-kernel, octavian.purdila, pebolle,
	patrick.porlan, adriana.reus, constantin.musca, marten,
	daniel.baluta, cristina.opriceana, pmeerw, viro, akpm

We don't want to hardcode default groups at subsystem
creation time. We export:
	* configfs_register_group
	* configfs_unregister_group
to allow drivers to programatically create/destroy groups
later, after module init time.

This is needed for IIO configfs support.

Suggested-by: Lars-Peter Clausen <lars@metafoo.de>
Signed-off-by: Daniel Baluta <daniel.baluta@intel.com>
---
 fs/configfs/dir.c        | 102 +++++++++++++++++++++++++++++++++++++++++++++++
 include/linux/configfs.h |   8 ++++
 2 files changed, 110 insertions(+)

diff --git a/fs/configfs/dir.c b/fs/configfs/dir.c
index c81ce7f..bf76795 100644
--- a/fs/configfs/dir.c
+++ b/fs/configfs/dir.c
@@ -1636,6 +1636,108 @@ const struct file_operations configfs_dir_operations = {
 	.iterate	= configfs_readdir,
 };
 
+/**
+ * configfs_alloc_group() - allocate a configfs group
+ * @name:	group name
+ * @item_type:	config_item associated with the allocated group
+ *
+ * Dynamically allocates and initialize a group specified by name and
+ * config_item_type. We need kzalloc'ed memory because default_group
+ * is empty.
+ *
+ * Return: allocated config group or ERR_PTR() on error
+ */
+struct config_group *
+configfs_alloc_group(const char *name, struct config_item_type *item_type)
+{
+	struct config_group *group;
+
+	group = kzalloc(sizeof(*group), GFP_KERNEL);
+	if (!group)
+		return ERR_PTR(-ENOMEM);
+	config_group_init_type_name(group, name, item_type);
+
+	return group;
+}
+EXPORT_SYMBOL(configfs_alloc_group);
+
+/**
+ * configfs_free_group() - frees memory for a configfs group
+ * @group:	group to be 'eliberated'
+ */
+void configfs_free_group(struct config_group *group)
+{
+	kfree(group);
+}
+EXPORT_SYMBOL(configfs_free_group);
+
+/**
+ * configfs_register_group - creates a parent-child relation between two groups
+ * @parent_group:	parent group
+ * @group:		child group
+ *
+ * link groups, creates dentry for the child and attaches it to the
+ * parent dentry.
+ *
+ * Return: 0 on success, negative errno code on error
+ */
+int configfs_register_group(struct config_group *parent_group,
+			    struct config_group *group)
+{
+	struct configfs_subsystem *subsys = parent_group->cg_subsys;
+	struct dentry *parent;
+	int ret;
+
+	mutex_lock(&subsys->su_mutex);
+	link_group(parent_group, group);
+	mutex_unlock(&subsys->su_mutex);
+
+	parent = parent_group->cg_item.ci_dentry;
+
+	mutex_lock_nested(&d_inode(parent)->i_mutex, I_MUTEX_PARENT);
+	ret = create_default_group(parent_group, group);
+	if (!ret) {
+		spin_lock(&configfs_dirent_lock);
+		configfs_dir_set_ready(group->cg_item.ci_dentry->d_fsdata);
+		spin_unlock(&configfs_dirent_lock);
+	}
+	mutex_unlock(&d_inode(parent)->i_mutex);
+	return ret;
+}
+EXPORT_SYMBOL(configfs_register_group);
+
+/**
+ * configfs_unregister_group() - unregisters a child group from its parent
+ *
+ * @group: parent group to be unregistered
+ *
+ * Undoes condigfs_register_group()
+ */
+void configfs_unregister_group(struct config_group *group)
+{
+	struct configfs_subsystem *subsys = group->cg_subsys;
+	struct dentry *dentry = group->cg_item.ci_dentry;
+	struct dentry *parent = group->cg_item.ci_parent->ci_dentry;
+
+	mutex_lock_nested(&d_inode(parent)->i_mutex, I_MUTEX_PARENT);
+	spin_lock(&configfs_dirent_lock);
+	configfs_detach_prep(dentry, NULL);
+	spin_unlock(&configfs_dirent_lock);
+
+	configfs_detach_group(&group->cg_item);
+	d_inode(dentry)->i_flags |= S_DEAD;
+	dont_mount(dentry);
+	d_delete(dentry);
+	mutex_unlock(&d_inode(parent)->i_mutex);
+
+	dput(dentry);
+
+	mutex_lock(&subsys->su_mutex);
+	unlink_group(group);
+	mutex_unlock(&subsys->su_mutex);
+}
+EXPORT_SYMBOL(configfs_unregister_group);
+
 int configfs_register_subsystem(struct configfs_subsystem *subsys)
 {
 	int err;
diff --git a/include/linux/configfs.h b/include/linux/configfs.h
index 63a36e8..c522a5e 100644
--- a/include/linux/configfs.h
+++ b/include/linux/configfs.h
@@ -252,6 +252,14 @@ static inline struct configfs_subsystem *to_configfs_subsystem(struct config_gro
 int configfs_register_subsystem(struct configfs_subsystem *subsys);
 void configfs_unregister_subsystem(struct configfs_subsystem *subsys);
 
+struct config_group *
+configfs_alloc_group(const char *name, struct config_item_type *item_type);
+void configfs_free_group(struct config_group *group);
+
+int configfs_register_group(struct config_group *parent_group,
+			    struct config_group *group);
+void configfs_unregister_group(struct config_group *group);
+
 /* These functions can sleep and can alloc with GFP_KERNEL */
 /* WARNING: These cannot be called underneath configfs callbacks!! */
 int configfs_depend_item(struct configfs_subsystem *subsys, struct config_item *target);
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH v9 2/5] iio: core: Introduce IIO configfs support
  2015-10-23 12:32 ` Daniel Baluta
  (?)
  (?)
@ 2015-10-23 12:32 ` Daniel Baluta
  -1 siblings, 0 replies; 12+ messages in thread
From: Daniel Baluta @ 2015-10-23 12:32 UTC (permalink / raw)
  To: jic23, jlbec, linux-iio, linux-fsdevel, lars, hch
  Cc: knaack.h, linux-kernel, octavian.purdila, pebolle,
	patrick.porlan, adriana.reus, constantin.musca, marten,
	daniel.baluta, cristina.opriceana, pmeerw, viro, akpm

This patch creates the IIO configfs root group. The group
will appear under <mount-point>/iio/, usually /config/iio.

We introduce configfs support in IIO in order to be able to easily
create IIO objects from userspace. The first supported IIO objects
are triggers introduced with next patches.

Signed-off-by: Daniel Baluta <daniel.baluta@intel.com>
---
 drivers/iio/Kconfig                 |  8 ++++++
 drivers/iio/Makefile                |  1 +
 drivers/iio/industrialio-configfs.c | 50 +++++++++++++++++++++++++++++++++++++
 3 files changed, 59 insertions(+)
 create mode 100644 drivers/iio/industrialio-configfs.c

diff --git a/drivers/iio/Kconfig b/drivers/iio/Kconfig
index 66792e7..d0f1ddb 100644
--- a/drivers/iio/Kconfig
+++ b/drivers/iio/Kconfig
@@ -22,6 +22,14 @@ if IIO_BUFFER
 	source "drivers/iio/buffer/Kconfig"
 endif # IIO_BUFFER
 
+config IIO_CONFIGFS
+	tristate "Enable IIO configuration via configfs"
+	select CONFIGFS_FS
+	help
+	  This allows configuring various IIO bits through configfs
+	  (e.g. software triggers). For more info see
+	  Documentation/iio/iio_configfs.txt.
+
 config IIO_TRIGGER
 	bool "Enable triggered sampling support"
 	help
diff --git a/drivers/iio/Makefile b/drivers/iio/Makefile
index aeca726..4e8ac82 100644
--- a/drivers/iio/Makefile
+++ b/drivers/iio/Makefile
@@ -7,6 +7,7 @@ industrialio-y := industrialio-core.o industrialio-event.o inkern.o
 industrialio-$(CONFIG_IIO_BUFFER) += industrialio-buffer.o
 industrialio-$(CONFIG_IIO_TRIGGER) += industrialio-trigger.o
 
+obj-$(CONFIG_IIO_CONFIGFS) += industrialio-configfs.o
 obj-$(CONFIG_IIO_TRIGGERED_EVENT) += industrialio-triggered-event.o
 
 obj-y += accel/
diff --git a/drivers/iio/industrialio-configfs.c b/drivers/iio/industrialio-configfs.c
new file mode 100644
index 0000000..83563dd
--- /dev/null
+++ b/drivers/iio/industrialio-configfs.c
@@ -0,0 +1,50 @@
+/*
+ * Industrial I/O configfs bits
+ *
+ * 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.
+ */
+
+#include <linux/configfs.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/kmod.h>
+#include <linux/slab.h>
+
+#include <linux/iio/iio.h>
+
+static struct config_item_type iio_root_group_type = {
+	.ct_owner       = THIS_MODULE,
+};
+
+struct configfs_subsystem iio_configfs_subsys = {
+	.su_group = {
+		.cg_item = {
+			.ci_namebuf = "iio",
+			.ci_type = &iio_root_group_type,
+		},
+	},
+	.su_mutex = __MUTEX_INITIALIZER(iio_configfs_subsys.su_mutex),
+};
+EXPORT_SYMBOL(iio_configfs_subsys);
+
+static int __init iio_configfs_init(void)
+{
+	config_group_init(&iio_configfs_subsys.su_group);
+
+	return configfs_register_subsystem(&iio_configfs_subsys);
+}
+module_init(iio_configfs_init);
+
+static void __exit iio_configfs_exit(void)
+{
+	configfs_unregister_subsystem(&iio_configfs_subsys);
+}
+module_exit(iio_configfs_exit);
+
+MODULE_AUTHOR("Daniel Baluta <daniel.baluta@intel.com>");
+MODULE_DESCRIPTION("Industrial I/O configfs support");
+MODULE_LICENSE("GPL v2");
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH v9 3/5] iio: core: Introduce IIO software triggers
  2015-10-23 12:32 ` Daniel Baluta
                   ` (2 preceding siblings ...)
  (?)
@ 2015-10-23 12:32 ` Daniel Baluta
  -1 siblings, 0 replies; 12+ messages in thread
From: Daniel Baluta @ 2015-10-23 12:32 UTC (permalink / raw)
  To: jic23, jlbec, linux-iio, linux-fsdevel, lars, hch
  Cc: knaack.h, linux-kernel, octavian.purdila, pebolle,
	patrick.porlan, adriana.reus, constantin.musca, marten,
	daniel.baluta, cristina.opriceana, pmeerw, viro, akpm

A software trigger associates an IIO device trigger with a software
interrupt source (e.g: timer, sysfs). This patch adds the generic
infrastructure for handling software triggers.

Software interrupts sources are kept in a iio_trigger_types_list and
registered separately when the associated kernel module is loaded.

Software triggers can be created directly from drivers or from user
space via configfs interface.

To sum up, this dynamically creates "triggers" group to be found under
/config/iio/triggers and offers the possibility of dynamically
creating trigger types group. The first support trigger type is
"hrtimer" found under /config/iio/triggers/hrtimer.

Signed-off-by: Daniel Baluta <daniel.baluta@intel.com>
---
 drivers/iio/Kconfig                   |   8 ++
 drivers/iio/Makefile                  |   1 +
 drivers/iio/industrialio-sw-trigger.c | 206 ++++++++++++++++++++++++++++++++++
 include/linux/iio/sw_trigger.h        |  71 ++++++++++++
 4 files changed, 286 insertions(+)
 create mode 100644 drivers/iio/industrialio-sw-trigger.c
 create mode 100644 include/linux/iio/sw_trigger.h

diff --git a/drivers/iio/Kconfig b/drivers/iio/Kconfig
index d0f1ddb..5dfb4f1 100644
--- a/drivers/iio/Kconfig
+++ b/drivers/iio/Kconfig
@@ -46,6 +46,14 @@ 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_TRIGGER
+	tristate "Enable software triggers support"
+	select IIO_CONFIGFS
+	help
+	 Provides IIO core support for software triggers. A software
+	 trigger can be created via configfs or directly by a driver
+	 using the API provided.
+
 config IIO_TRIGGERED_EVENT
 	tristate
 	select IIO_TRIGGER
diff --git a/drivers/iio/Makefile b/drivers/iio/Makefile
index 4e8ac82..dc73c1f 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_TRIGGER) += industrialio-sw-trigger.o
 obj-$(CONFIG_IIO_TRIGGERED_EVENT) += industrialio-triggered-event.o
 
 obj-y += accel/
diff --git a/drivers/iio/industrialio-sw-trigger.c b/drivers/iio/industrialio-sw-trigger.c
new file mode 100644
index 0000000..8911f22
--- /dev/null
+++ b/drivers/iio/industrialio-sw-trigger.c
@@ -0,0 +1,206 @@
+/*
+ * The Industrial I/O core, software trigger functions
+ *
+ * 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.
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/kmod.h>
+#include <linux/list.h>
+#include <linux/slab.h>
+
+#include <linux/iio/sw_trigger.h>
+#include <linux/configfs.h>
+
+static struct config_group *iio_triggers_group;
+static struct config_item_type iio_triggers_group_type = {
+	.ct_owner = THIS_MODULE,
+};
+
+static LIST_HEAD(iio_trigger_types_list);
+static DEFINE_MUTEX(iio_trigger_types_lock);
+
+static
+struct iio_sw_trigger_type *__iio_find_sw_trigger_type(const char *name,
+						       unsigned len)
+{
+	struct iio_sw_trigger_type *t = NULL, *iter;
+
+	list_for_each_entry(iter, &iio_trigger_types_list, list)
+		if (!strcmp(iter->name, name)) {
+			t = iter;
+			break;
+		}
+
+	return t;
+}
+
+int iio_register_sw_trigger_type(struct iio_sw_trigger_type *t)
+{
+	struct iio_sw_trigger_type *iter;
+	int ret = 0;
+
+	mutex_lock(&iio_trigger_types_lock);
+	iter = __iio_find_sw_trigger_type(t->name, strlen(t->name));
+	if (iter)
+		ret = -EBUSY;
+	else
+		list_add_tail(&t->list, &iio_trigger_types_list);
+	mutex_unlock(&iio_trigger_types_lock);
+
+	if (!ret)
+		iio_sw_trigger_type_configfs_register(t);
+
+	return ret;
+}
+EXPORT_SYMBOL(iio_register_sw_trigger_type);
+
+void iio_unregister_sw_trigger_type(struct iio_sw_trigger_type *t)
+{
+	struct iio_sw_trigger_type *iter;
+
+	mutex_lock(&iio_trigger_types_lock);
+	iter = __iio_find_sw_trigger_type(t->name, strlen(t->name));
+	if (iter)
+		list_del(&t->list);
+	mutex_unlock(&iio_trigger_types_lock);
+
+	iio_sw_trigger_type_configfs_unregister(t);
+}
+EXPORT_SYMBOL(iio_unregister_sw_trigger_type);
+
+static
+struct iio_sw_trigger_type *iio_get_sw_trigger_type(const char *name)
+{
+	struct iio_sw_trigger_type *t;
+
+	mutex_lock(&iio_trigger_types_lock);
+	t = __iio_find_sw_trigger_type(name, strlen(name));
+	if (t && !try_module_get(t->owner))
+		t = NULL;
+	mutex_unlock(&iio_trigger_types_lock);
+
+	return t;
+}
+
+struct iio_sw_trigger *iio_sw_trigger_create(const char *type, const char *name)
+{
+	struct iio_sw_trigger *t;
+	struct iio_sw_trigger_type *tt;
+
+	tt = iio_get_sw_trigger_type(type);
+	if (!tt) {
+		pr_err("Invalid trigger type: %s\n", type);
+		return ERR_PTR(-EINVAL);
+	}
+	t = tt->ops->probe(name);
+	if (IS_ERR(t))
+		goto out_module_put;
+
+	t->trigger_type = tt;
+
+	return t;
+out_module_put:
+	module_put(tt->owner);
+	return t;
+}
+EXPORT_SYMBOL(iio_sw_trigger_create);
+
+void iio_sw_trigger_destroy(struct iio_sw_trigger *t)
+{
+	struct iio_sw_trigger_type *tt = t->trigger_type;
+
+	tt->ops->remove(t);
+	module_put(tt->owner);
+}
+EXPORT_SYMBOL(iio_sw_trigger_destroy);
+
+static struct config_group *trigger_make_group(struct config_group *group,
+					       const char *name)
+{
+	struct iio_sw_trigger *t;
+
+	t = iio_sw_trigger_create(group->cg_item.ci_name, name);
+	if (IS_ERR(t))
+		return ERR_CAST(t);
+
+	config_item_set_name(&t->group.cg_item, "%s", name);
+
+	return &t->group;
+}
+
+static void trigger_drop_group(struct config_group *group,
+			       struct config_item *item)
+{
+	struct iio_sw_trigger *t = to_iio_sw_trigger(item);
+
+	iio_sw_trigger_destroy(t);
+	config_item_put(item);
+}
+
+static struct configfs_group_operations trigger_ops = {
+	.make_group	= &trigger_make_group,
+	.drop_item	= &trigger_drop_group,
+};
+
+static struct config_item_type iio_trigger_type_group_type = {
+	.ct_group_ops = &trigger_ops,
+	.ct_owner       = THIS_MODULE,
+};
+
+int iio_sw_trigger_type_configfs_register(struct iio_sw_trigger_type *tt)
+{
+	int ret;
+
+	tt->group = configfs_alloc_group(tt->name,
+					 &iio_trigger_type_group_type);
+	if (IS_ERR(tt->group))
+		return PTR_ERR(tt->group);
+
+	ret = configfs_register_group(iio_triggers_group, tt->group);
+	if (ret)
+		configfs_free_group(tt->group);
+	return ret;
+}
+EXPORT_SYMBOL_GPL(iio_sw_trigger_type_configfs_register);
+
+void iio_sw_trigger_type_configfs_unregister(struct iio_sw_trigger_type *tt)
+{
+	configfs_unregister_group(tt->group);
+	configfs_free_group(tt->group);
+}
+EXPORT_SYMBOL_GPL(iio_sw_trigger_type_configfs_unregister);
+
+static int __init iio_sw_trigger_init(void)
+{
+	int ret;
+
+	iio_triggers_group = configfs_alloc_group("triggers",
+						  &iio_triggers_group_type);
+	if (IS_ERR(iio_triggers_group))
+		return PTR_ERR(iio_triggers_group);
+
+	ret = configfs_register_group(&iio_configfs_subsys.su_group,
+				      iio_triggers_group);
+	if (ret)
+		configfs_free_group(iio_triggers_group);
+
+	return ret;
+}
+module_init(iio_sw_trigger_init);
+
+static void __exit iio_sw_trigger_exit(void)
+{
+	configfs_unregister_group(iio_triggers_group);
+	configfs_free_group(iio_triggers_group);
+}
+module_exit(iio_sw_trigger_exit);
+
+MODULE_AUTHOR("Daniel Baluta <daniel.baluta@intel.com>");
+MODULE_DESCRIPTION("Industrial I/O software triggers support");
+MODULE_LICENSE("GPL v2");
diff --git a/include/linux/iio/sw_trigger.h b/include/linux/iio/sw_trigger.h
new file mode 100644
index 0000000..c2f33b2
--- /dev/null
+++ b/include/linux/iio/sw_trigger.h
@@ -0,0 +1,71 @@
+/*
+ * Industrial I/O software trigger 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_TRIGGER
+#define __IIO_SW_TRIGGER
+
+#include <linux/module.h>
+#include <linux/device.h>
+#include <linux/iio/iio.h>
+#include <linux/configfs.h>
+
+#define module_iio_sw_trigger_driver(__iio_sw_trigger_type) \
+	module_driver(__iio_sw_trigger_type, iio_register_sw_trigger_type, \
+		      iio_unregister_sw_trigger_type)
+
+extern struct configfs_subsystem iio_configfs_subsys;
+struct iio_sw_trigger_ops;
+
+struct iio_sw_trigger_type {
+	const char *name;
+	struct module *owner;
+	const struct iio_sw_trigger_ops *ops;
+	struct list_head list;
+	struct config_group *group;
+};
+
+struct iio_sw_trigger {
+	struct iio_trigger *trigger;
+	struct iio_sw_trigger_type *trigger_type;
+	struct config_group group;
+};
+
+struct iio_sw_trigger_ops {
+	struct iio_sw_trigger* (*probe)(const char *);
+	int (*remove)(struct iio_sw_trigger *);
+};
+
+static inline
+struct iio_sw_trigger *to_iio_sw_trigger(struct config_item *item)
+{
+	return container_of(to_config_group(item), struct iio_sw_trigger,
+			    group);
+}
+
+int iio_register_sw_trigger_type(struct iio_sw_trigger_type *tt);
+void iio_unregister_sw_trigger_type(struct iio_sw_trigger_type *tt);
+
+struct iio_sw_trigger *iio_sw_trigger_create(const char *, const char *);
+void iio_sw_trigger_destroy(struct iio_sw_trigger *);
+
+int iio_sw_trigger_type_configfs_register(struct iio_sw_trigger_type *tt);
+void iio_sw_trigger_type_configfs_unregister(struct iio_sw_trigger_type *tt);
+
+static inline
+void iio_swt_group_init_type_name(struct iio_sw_trigger *t,
+				  const char *name,
+				  struct config_item_type *type)
+{
+#ifdef CONFIG_CONFIGFS_FS
+	config_group_init_type_name(&t->group, name, type);
+#endif
+}
+
+#endif /* __IIO_SW_TRIGGER */
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH v9 4/5] iio: trigger: Introduce IIO hrtimer based trigger
  2015-10-23 12:32 ` Daniel Baluta
                   ` (3 preceding siblings ...)
  (?)
@ 2015-10-23 12:32 ` Daniel Baluta
  2015-10-24  9:10     ` Matt Ranostay
  -1 siblings, 1 reply; 12+ messages in thread
From: Daniel Baluta @ 2015-10-23 12:32 UTC (permalink / raw)
  To: jic23, jlbec, linux-iio, linux-fsdevel, lars, hch
  Cc: knaack.h, linux-kernel, octavian.purdila, pebolle,
	patrick.porlan, adriana.reus, constantin.musca, marten,
	daniel.baluta, cristina.opriceana, pmeerw, viro, akpm

This patch registers a new IIO software trigger interrupt source
based on high resolution timers.

Notice that if configfs is enabled we create sampling_frequency
attribute allowing users to change hrtimer period (1/sampling_frequency).

The IIO hrtimer trigger has a long history, this patch is based on
an older version from Marten and Lars-Peter.

Signed-off-by: Marten Svanfeldt <marten@intuitiveaerial.com>
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
Signed-off-by: Daniel Baluta <daniel.baluta@intel.com>
---
 drivers/iio/trigger/Kconfig            |  10 ++
 drivers/iio/trigger/Makefile           |   2 +
 drivers/iio/trigger/iio-trig-hrtimer.c | 193 +++++++++++++++++++++++++++++++++
 3 files changed, 205 insertions(+)
 create mode 100644 drivers/iio/trigger/iio-trig-hrtimer.c

diff --git a/drivers/iio/trigger/Kconfig b/drivers/iio/trigger/Kconfig
index 7999612..519e677 100644
--- a/drivers/iio/trigger/Kconfig
+++ b/drivers/iio/trigger/Kconfig
@@ -5,6 +5,16 @@
 
 menu "Triggers - standalone"
 
+config IIO_HRTIMER_TRIGGER
+	tristate "High resolution timer trigger"
+	depends on IIO_SW_TRIGGER
+	help
+	  Provides a frequency based IIO trigger using high resolution
+	  timers as interrupt source.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called iio-trig-hrtimer.
+
 config IIO_INTERRUPT_TRIGGER
 	tristate "Generic interrupt trigger"
 	help
diff --git a/drivers/iio/trigger/Makefile b/drivers/iio/trigger/Makefile
index 0694dae..fe06eb5 100644
--- a/drivers/iio/trigger/Makefile
+++ b/drivers/iio/trigger/Makefile
@@ -3,5 +3,7 @@
 #
 
 # When adding new entries keep the list in alphabetical order
+
+obj-$(CONFIG_IIO_HRTIMER_TRIGGER) += iio-trig-hrtimer.o
 obj-$(CONFIG_IIO_INTERRUPT_TRIGGER) += iio-trig-interrupt.o
 obj-$(CONFIG_IIO_SYSFS_TRIGGER) += iio-trig-sysfs.o
diff --git a/drivers/iio/trigger/iio-trig-hrtimer.c b/drivers/iio/trigger/iio-trig-hrtimer.c
new file mode 100644
index 0000000..5e6d451
--- /dev/null
+++ b/drivers/iio/trigger/iio-trig-hrtimer.c
@@ -0,0 +1,193 @@
+/**
+ * The industrial I/O periodic hrtimer trigger driver
+ *
+ * Copyright (C) Intuitive Aerial AB
+ * Written by Marten Svanfeldt, marten@intuitiveaerial.com
+ * Copyright (C) 2012, Analog Device Inc.
+ *	Author: Lars-Peter Clausen <lars@metafoo.de>
+ * 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.
+ *
+ */
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/hrtimer.h>
+
+#include <linux/iio/iio.h>
+#include <linux/iio/trigger.h>
+#include <linux/iio/sw_trigger.h>
+
+/* default sampling frequency - 100Hz */
+#define HRTIMER_DEFAULT_SAMPLING_FREQUENCY 100
+
+struct iio_hrtimer_info {
+	struct iio_sw_trigger swt;
+	struct hrtimer timer;
+	unsigned long sampling_frequency;
+	ktime_t period;
+};
+
+static struct config_item_type iio_hrtimer_type = {
+	.ct_owner = THIS_MODULE,
+};
+
+static
+ssize_t iio_hrtimer_show_sampling_frequency(struct device *dev,
+					    struct device_attribute *attr,
+					    char *buf)
+{
+	struct iio_trigger *trig = to_iio_trigger(dev);
+	struct iio_hrtimer_info *info = iio_trigger_get_drvdata(trig);
+
+	return snprintf(buf, PAGE_SIZE, "%lu\n", info->sampling_frequency);
+}
+
+static
+ssize_t iio_hrtimer_store_sampling_frequency(struct device *dev,
+					     struct device_attribute *attr,
+					     const char *buf, size_t len)
+{
+	struct iio_trigger *trig = to_iio_trigger(dev);
+	struct iio_hrtimer_info *info = iio_trigger_get_drvdata(trig);
+	unsigned long val;
+	int ret;
+
+	ret = kstrtoul(buf, 10, &val);
+	if (ret)
+		return ret;
+
+	if (!val || val > NSEC_PER_SEC)
+		return -EINVAL;
+
+	info->sampling_frequency = val;
+	info->period = ktime_set(0, NSEC_PER_SEC / val);
+
+	return len;
+}
+
+static DEVICE_ATTR(sampling_frequency, S_IRUGO | S_IWUSR,
+		   iio_hrtimer_show_sampling_frequency,
+		   iio_hrtimer_store_sampling_frequency);
+
+static struct attribute *iio_hrtimer_attrs[] = {
+	&dev_attr_sampling_frequency.attr,
+	NULL
+};
+
+static const struct attribute_group iio_hrtimer_attr_group = {
+	.attrs = iio_hrtimer_attrs,
+};
+
+static const struct attribute_group *iio_hrtimer_attr_groups[] = {
+	&iio_hrtimer_attr_group,
+	NULL
+};
+
+static enum hrtimer_restart iio_hrtimer_trig_handler(struct hrtimer *timer)
+{
+	struct iio_hrtimer_info *info;
+
+	info = container_of(timer, struct iio_hrtimer_info, timer);
+
+	hrtimer_forward_now(timer, info->period);
+	iio_trigger_poll(info->swt.trigger);
+
+	return HRTIMER_RESTART;
+}
+
+static int iio_trig_hrtimer_set_state(struct iio_trigger *trig, bool state)
+{
+	struct iio_hrtimer_info *trig_info;
+
+	trig_info = iio_trigger_get_drvdata(trig);
+
+	if (state)
+		hrtimer_start(&trig_info->timer, trig_info->period,
+			      HRTIMER_MODE_REL);
+	else
+		hrtimer_cancel(&trig_info->timer);
+
+	return 0;
+}
+
+static const struct iio_trigger_ops iio_hrtimer_trigger_ops = {
+	.owner = THIS_MODULE,
+	.set_trigger_state = iio_trig_hrtimer_set_state,
+};
+
+static struct iio_sw_trigger *iio_trig_hrtimer_probe(const char *name)
+{
+	struct iio_hrtimer_info *trig_info;
+	int ret;
+
+	trig_info = kzalloc(sizeof(*trig_info), GFP_KERNEL);
+	if (!trig_info)
+		return ERR_PTR(-ENOMEM);
+
+	trig_info->swt.trigger = iio_trigger_alloc("%s", name);
+	if (!trig_info->swt.trigger) {
+		ret = -ENOMEM;
+		goto err_free_trig_info;
+	}
+
+	iio_trigger_set_drvdata(trig_info->swt.trigger, trig_info);
+	trig_info->swt.trigger->ops = &iio_hrtimer_trigger_ops;
+	trig_info->swt.trigger->dev.groups = iio_hrtimer_attr_groups;
+
+	hrtimer_init(&trig_info->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
+	trig_info->timer.function = iio_hrtimer_trig_handler;
+
+	trig_info->sampling_frequency = HRTIMER_DEFAULT_SAMPLING_FREQUENCY;
+	trig_info->period = ktime_set(0, NSEC_PER_SEC /
+				      trig_info->sampling_frequency);
+
+	ret = iio_trigger_register(trig_info->swt.trigger);
+	if (ret)
+		goto err_free_trigger;
+
+	iio_swt_group_init_type_name(&trig_info->swt, name, &iio_hrtimer_type);
+	return &trig_info->swt;
+err_free_trigger:
+	iio_trigger_free(trig_info->swt.trigger);
+err_free_trig_info:
+	kfree(trig_info);
+
+	return ERR_PTR(ret);
+}
+
+static int iio_trig_hrtimer_remove(struct iio_sw_trigger *swt)
+{
+	struct iio_hrtimer_info *trig_info;
+
+	trig_info = iio_trigger_get_drvdata(swt->trigger);
+
+	iio_trigger_unregister(swt->trigger);
+
+	/* cancel the timer after unreg to make sure no one rearms it */
+	hrtimer_cancel(&trig_info->timer);
+	iio_trigger_free(swt->trigger);
+	kfree(trig_info);
+
+	return 0;
+}
+
+static const struct iio_sw_trigger_ops iio_trig_hrtimer_ops = {
+	.probe		= iio_trig_hrtimer_probe,
+	.remove		= iio_trig_hrtimer_remove,
+};
+
+static struct iio_sw_trigger_type iio_trig_hrtimer = {
+	.name = "hrtimer",
+	.owner = THIS_MODULE,
+	.ops = &iio_trig_hrtimer_ops,
+};
+
+module_iio_sw_trigger_driver(iio_trig_hrtimer);
+
+MODULE_AUTHOR("Marten Svanfeldt <marten@intuitiveaerial.com>");
+MODULE_AUTHOR("Daniel Baluta <daniel.baluta@intel.com>");
+MODULE_DESCRIPTION("Periodic hrtimer trigger for the IIO subsystem");
+MODULE_LICENSE("GPL v2");
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH v9 5/5] iio: Documentation: Add IIO configfs documentation
  2015-10-23 12:32 ` Daniel Baluta
                   ` (4 preceding siblings ...)
  (?)
@ 2015-10-23 12:32 ` Daniel Baluta
  -1 siblings, 0 replies; 12+ messages in thread
From: Daniel Baluta @ 2015-10-23 12:32 UTC (permalink / raw)
  To: jic23, jlbec, linux-iio, linux-fsdevel, lars, hch
  Cc: knaack.h, linux-kernel, octavian.purdila, pebolle,
	patrick.porlan, adriana.reus, constantin.musca, marten,
	daniel.baluta, cristina.opriceana, pmeerw, viro, akpm

Signed-off-by: Daniel Baluta <daniel.baluta@intel.com>
---
 Documentation/ABI/testing/configfs-iio | 21 ++++++++
 Documentation/iio/iio_configfs.txt     | 93 ++++++++++++++++++++++++++++++++++
 2 files changed, 114 insertions(+)
 create mode 100644 Documentation/ABI/testing/configfs-iio
 create mode 100644 Documentation/iio/iio_configfs.txt

diff --git a/Documentation/ABI/testing/configfs-iio b/Documentation/ABI/testing/configfs-iio
new file mode 100644
index 0000000..2483756
--- /dev/null
+++ b/Documentation/ABI/testing/configfs-iio
@@ -0,0 +1,21 @@
+What:		/config/iio
+Date:		October 2015
+KernelVersion:	4.4
+Contact:	linux-iio@vger.kernel.org
+Description:
+		This represents Industrial IO configuration entry point
+		directory. It contains sub-groups corresponding to IIO
+		objects.
+
+What:		/config/iio/triggers
+Date:		October 2015
+KernelVersion:	4.4
+Description:
+		Industrial IO software triggers directory.
+
+What:		/config/iio/triggers/hrtimers
+Date:		October 2015
+KernelVersion:	4.4
+Description:
+		High resolution timers directory. Creating a directory here
+		will result in creating a hrtimer trigger in the IIO subsystem.
diff --git a/Documentation/iio/iio_configfs.txt b/Documentation/iio/iio_configfs.txt
new file mode 100644
index 0000000..f0add35
--- /dev/null
+++ b/Documentation/iio/iio_configfs.txt
@@ -0,0 +1,93 @@
+Industrial IIO configfs support
+
+1. Overview
+
+Configfs is a filesystem-based manager of kernel objects. IIO uses some
+objects that could be easily configured using configfs (e.g.: devices,
+triggers).
+
+See Documentation/filesystems/configfs/configfs.txt for more information
+about how configfs works.
+
+2. Usage
+
+In order to use configfs support in IIO we need to select it at compile
+time via CONFIG_IIO_CONFIGFS config option.
+
+Then, mount the configfs filesystem (usually under /config directory):
+
+$ mkdir /config
+$ mount -t configfs none /config
+
+At this point, all default IIO groups will be created and can be accessed
+under /config/iio. Next chapters will describe available IIO configuration
+objects.
+
+3. Software triggers
+
+One of the IIO default configfs groups is the "triggers" group. It is
+automagically accessible when the configfs is mounted and can be found
+under /config/iio/triggers.
+
+IIO software triggers implementation offers support for creating multiple
+trigger types. A new trigger type is usually implemented as a separate
+kernel module following the interface in include/linux/iio/sw_trigger.h:
+
+/*
+ * drivers/iio/trigger/iio-trig-sample.c
+ * sample kernel module implementing a new trigger type
+ */
+#include <linux/iio/sw_trigger.h>
+
+
+static struct iio_sw_trigger *iio_trig_sample_probe(const char *name)
+{
+	/*
+	 * This allocates and registers an IIO trigger plus other
+	 * trigger type specific initialization.
+	 */
+}
+
+static int iio_trig_hrtimer_remove(struct iio_sw_trigger *swt)
+{
+	/*
+	 * This undoes the actions in iio_trig_sample_probe
+	 */
+}
+
+static const struct iio_sw_trigger_ops iio_trig_sample_ops = {
+	.probe		= iio_trig_sample_probe,
+	.remove		= iio_trig_sample_remove,
+};
+
+static struct iio_sw_trigger_type iio_trig_sample = {
+	.name = "trig-sample",
+	.owner = THIS_MODULE,
+	.ops = &iio_trig_sample_ops,
+};
+
+module_iio_sw_trigger_driver(iio_trig_sample);
+
+Each trigger type has its own directory under /config/iio/triggers. Loading
+iio-trig-sample module will create 'trig-sample' trigger type directory
+/config/iio/triggers/trig-sample.
+
+We support the following interrupt sources (trigger types):
+	* hrtimer, uses high resolution timers as interrupt source
+
+3.1 Hrtimer triggers creation and destruction
+
+Loading iio-trig-hrtimer module will register hrtimer trigger types allowing
+users to create hrtimer triggers under /config/iio/triggers/hrtimer.
+
+e.g:
+
+$ mkdir /config/triggers/hrtimer/instance1
+$ rmdir /config/triggers/hrtimer/instance1
+
+Each trigger can have one or more attributes specific to the trigger type.
+
+3.2 "hrtimer" trigger types attributes
+
+"hrtimer" trigger type doesn't have any configurable attribute from /config dir.
+It does introduce the sampling_frequency attribute to trigger directory.
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* Re: [PATCH v9 1/5] configfs: Allow dynamic group creation
  2015-10-23 12:32 ` [PATCH v9 1/5] configfs: Allow dynamic group creation Daniel Baluta
@ 2015-10-23 12:48   ` Christoph Hellwig
  2015-10-23 13:08     ` Daniel Baluta
  2015-10-23 14:09     ` Daniel Baluta
  0 siblings, 2 replies; 12+ messages in thread
From: Christoph Hellwig @ 2015-10-23 12:48 UTC (permalink / raw)
  To: Daniel Baluta
  Cc: jic23, jlbec, linux-iio, linux-fsdevel, lars, hch, knaack.h,
	linux-kernel, octavian.purdila, pebolle, patrick.porlan,
	adriana.reus, constantin.musca, marten, cristina.opriceana,
	pmeerw, viro, akpm

Hi Daniel,

all these functions look great, but can you also move your new
iio_sw_trigger_type_configfs_register/unregister functions to the
core code as those are the wrappers that everyone would have to write,
e.g. something like:

int configfs_register_default_group(struct config_group *parent_group,
		const char *name, struct config_item_type *item_type)
{
	struct config_group *group;

	group = kzalloc(sizeof(*group), GFP_KERNEL);
	if (!group)
		return -ENOMEM;
	config_group_init_type_name(group, name, item_type);

	ret = configfs_register_group(parent_group, group);
	if (ret)
		kfree(group);
	return ret;
}

and the same on the unregister side?

With that:

Reviewed-by: Christoph Hellwig <hch@lst.de>

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH v9 1/5] configfs: Allow dynamic group creation
  2015-10-23 12:48   ` Christoph Hellwig
@ 2015-10-23 13:08     ` Daniel Baluta
  2015-10-23 14:09     ` Daniel Baluta
  1 sibling, 0 replies; 12+ messages in thread
From: Daniel Baluta @ 2015-10-23 13:08 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Daniel Baluta, Jonathan Cameron, Joel Becker, linux-iio,
	linux-fsdevel, Lars-Peter Clausen, Hartmut Knaack,
	Linux Kernel Mailing List, octavian.purdila, Paul Bolle,
	patrick.porlan, Adriana Reus, constantin.musca, marten,
	Cristina Georgiana Opriceana, Peter Meerwald, viro,
	Andrew Morton

On Fri, Oct 23, 2015 at 3:48 PM, Christoph Hellwig <hch@lst.de> wrote:
> Hi Daniel,
>
> all these functions look great, but can you also move your new
> iio_sw_trigger_type_configfs_register/unregister functions to the
> core code as those are the wrappers that everyone would have to write,
> e.g. something like:
>
> int configfs_register_default_group(struct config_group *parent_group,
>                 const char *name, struct config_item_type *item_type)
> {
>         struct config_group *group;
>
>         group = kzalloc(sizeof(*group), GFP_KERNEL);
>         if (!group)
>                 return -ENOMEM;
>         config_group_init_type_name(group, name, item_type);
>
>         ret = configfs_register_group(parent_group, group);
>         if (ret)
>                 kfree(group);
>         return ret;
> }
>
> and the same on the unregister side?
Yes, this is a good idea. Will do!
>
> With that:
>
> Reviewed-by: Christoph Hellwig <hch@lst.de>

thanks,
Daniel.

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH v9 1/5] configfs: Allow dynamic group creation
  2015-10-23 12:48   ` Christoph Hellwig
  2015-10-23 13:08     ` Daniel Baluta
@ 2015-10-23 14:09     ` Daniel Baluta
  1 sibling, 0 replies; 12+ messages in thread
From: Daniel Baluta @ 2015-10-23 14:09 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Daniel Baluta, Jonathan Cameron, Joel Becker, linux-iio,
	linux-fsdevel, Lars-Peter Clausen, Hartmut Knaack,
	Linux Kernel Mailing List, octavian.purdila, Paul Bolle,
	patrick.porlan, Adriana Reus, constantin.musca, marten,
	Cristina Georgiana Opriceana, Peter Meerwald, viro,
	Andrew Morton

Christoph, one question. See below.

On Fri, Oct 23, 2015 at 3:48 PM, Christoph Hellwig <hch@lst.de> wrote:
> Hi Daniel,
>
> all these functions look great, but can you also move your new
> iio_sw_trigger_type_configfs_register/unregister functions to the
> core code as those are the wrappers that everyone would have to write,
> e.g. something like:
>
> int configfs_register_default_group(struct config_group *parent_group,
>                 const char *name, struct config_item_type *item_type)
> {
>         struct config_group *group;
>
>         group = kzalloc(sizeof(*group), GFP_KERNEL);
>         if (!group)
>                 return -ENOMEM;
>         config_group_init_type_name(group, name, item_type);

Until this point this is the implementation of configfs_alloc_group.

We have two options:

1) Remove configfs_alloc_group/configfs_free_group as people will directly
use our new configfs_register_default_group that does the allocation.

2) Keep configfs_alloc/group/configfs_gree_group and use it here.

I'm in favour of 1) variant, as it makes little sense to have a wrapper over
kmalloc + config_group_init_type_name.

thanks,
Daniel.

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH v9 4/5] iio: trigger: Introduce IIO hrtimer based trigger
@ 2015-10-24  9:10     ` Matt Ranostay
  0 siblings, 0 replies; 12+ messages in thread
From: Matt Ranostay @ 2015-10-24  9:10 UTC (permalink / raw)
  To: Daniel Baluta
  Cc: Jonathan Cameron, jlbec, linux-iio, linux-fsdevel,
	Lars-Peter Clausen, hch, Hartmut Knaack, linux-kernel,
	octavian.purdila, pebolle, patrick.porlan, adriana.reus,
	constantin.musca, marten, cristina.opriceana, Peter Meerwald,
	viro, akpm

Tested-by: Matt Ranostay <matt.ranostay@intel.com>

On Fri, Oct 23, 2015 at 5:32 AM, Daniel Baluta <daniel.baluta@intel.com> wrote:
> This patch registers a new IIO software trigger interrupt source
> based on high resolution timers.
>
> Notice that if configfs is enabled we create sampling_frequency
> attribute allowing users to change hrtimer period (1/sampling_frequency).
>
> The IIO hrtimer trigger has a long history, this patch is based on
> an older version from Marten and Lars-Peter.
>
> Signed-off-by: Marten Svanfeldt <marten@intuitiveaerial.com>
> Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
> Signed-off-by: Daniel Baluta <daniel.baluta@intel.com>
> ---
>  drivers/iio/trigger/Kconfig            |  10 ++
>  drivers/iio/trigger/Makefile           |   2 +
>  drivers/iio/trigger/iio-trig-hrtimer.c | 193 +++++++++++++++++++++++++++++++++
>  3 files changed, 205 insertions(+)
>  create mode 100644 drivers/iio/trigger/iio-trig-hrtimer.c
>
> diff --git a/drivers/iio/trigger/Kconfig b/drivers/iio/trigger/Kconfig
> index 7999612..519e677 100644
> --- a/drivers/iio/trigger/Kconfig
> +++ b/drivers/iio/trigger/Kconfig
> @@ -5,6 +5,16 @@
>
>  menu "Triggers - standalone"
>
> +config IIO_HRTIMER_TRIGGER
> +       tristate "High resolution timer trigger"
> +       depends on IIO_SW_TRIGGER
> +       help
> +         Provides a frequency based IIO trigger using high resolution
> +         timers as interrupt source.
> +
> +         To compile this driver as a module, choose M here: the
> +         module will be called iio-trig-hrtimer.
> +
>  config IIO_INTERRUPT_TRIGGER
>         tristate "Generic interrupt trigger"
>         help
> diff --git a/drivers/iio/trigger/Makefile b/drivers/iio/trigger/Makefile
> index 0694dae..fe06eb5 100644
> --- a/drivers/iio/trigger/Makefile
> +++ b/drivers/iio/trigger/Makefile
> @@ -3,5 +3,7 @@
>  #
>
>  # When adding new entries keep the list in alphabetical order
> +
> +obj-$(CONFIG_IIO_HRTIMER_TRIGGER) += iio-trig-hrtimer.o
>  obj-$(CONFIG_IIO_INTERRUPT_TRIGGER) += iio-trig-interrupt.o
>  obj-$(CONFIG_IIO_SYSFS_TRIGGER) += iio-trig-sysfs.o
> diff --git a/drivers/iio/trigger/iio-trig-hrtimer.c b/drivers/iio/trigger/iio-trig-hrtimer.c
> new file mode 100644
> index 0000000..5e6d451
> --- /dev/null
> +++ b/drivers/iio/trigger/iio-trig-hrtimer.c
> @@ -0,0 +1,193 @@
> +/**
> + * The industrial I/O periodic hrtimer trigger driver
> + *
> + * Copyright (C) Intuitive Aerial AB
> + * Written by Marten Svanfeldt, marten@intuitiveaerial.com
> + * Copyright (C) 2012, Analog Device Inc.
> + *     Author: Lars-Peter Clausen <lars@metafoo.de>
> + * 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.
> + *
> + */
> +#include <linux/kernel.h>
> +#include <linux/slab.h>
> +#include <linux/hrtimer.h>
> +
> +#include <linux/iio/iio.h>
> +#include <linux/iio/trigger.h>
> +#include <linux/iio/sw_trigger.h>
> +
> +/* default sampling frequency - 100Hz */
> +#define HRTIMER_DEFAULT_SAMPLING_FREQUENCY 100
> +
> +struct iio_hrtimer_info {
> +       struct iio_sw_trigger swt;
> +       struct hrtimer timer;
> +       unsigned long sampling_frequency;
> +       ktime_t period;
> +};
> +
> +static struct config_item_type iio_hrtimer_type = {
> +       .ct_owner = THIS_MODULE,
> +};
> +
> +static
> +ssize_t iio_hrtimer_show_sampling_frequency(struct device *dev,
> +                                           struct device_attribute *attr,
> +                                           char *buf)
> +{
> +       struct iio_trigger *trig = to_iio_trigger(dev);
> +       struct iio_hrtimer_info *info = iio_trigger_get_drvdata(trig);
> +
> +       return snprintf(buf, PAGE_SIZE, "%lu\n", info->sampling_frequency);
> +}
> +
> +static
> +ssize_t iio_hrtimer_store_sampling_frequency(struct device *dev,
> +                                            struct device_attribute *attr,
> +                                            const char *buf, size_t len)
> +{
> +       struct iio_trigger *trig = to_iio_trigger(dev);
> +       struct iio_hrtimer_info *info = iio_trigger_get_drvdata(trig);
> +       unsigned long val;
> +       int ret;
> +
> +       ret = kstrtoul(buf, 10, &val);
> +       if (ret)
> +               return ret;
> +
> +       if (!val || val > NSEC_PER_SEC)
> +               return -EINVAL;
> +
> +       info->sampling_frequency = val;
> +       info->period = ktime_set(0, NSEC_PER_SEC / val);
> +
> +       return len;
> +}
> +
> +static DEVICE_ATTR(sampling_frequency, S_IRUGO | S_IWUSR,
> +                  iio_hrtimer_show_sampling_frequency,
> +                  iio_hrtimer_store_sampling_frequency);
> +
> +static struct attribute *iio_hrtimer_attrs[] = {
> +       &dev_attr_sampling_frequency.attr,
> +       NULL
> +};
> +
> +static const struct attribute_group iio_hrtimer_attr_group = {
> +       .attrs = iio_hrtimer_attrs,
> +};
> +
> +static const struct attribute_group *iio_hrtimer_attr_groups[] = {
> +       &iio_hrtimer_attr_group,
> +       NULL
> +};
> +
> +static enum hrtimer_restart iio_hrtimer_trig_handler(struct hrtimer *timer)
> +{
> +       struct iio_hrtimer_info *info;
> +
> +       info = container_of(timer, struct iio_hrtimer_info, timer);
> +
> +       hrtimer_forward_now(timer, info->period);
> +       iio_trigger_poll(info->swt.trigger);
> +
> +       return HRTIMER_RESTART;
> +}
> +
> +static int iio_trig_hrtimer_set_state(struct iio_trigger *trig, bool state)
> +{
> +       struct iio_hrtimer_info *trig_info;
> +
> +       trig_info = iio_trigger_get_drvdata(trig);
> +
> +       if (state)
> +               hrtimer_start(&trig_info->timer, trig_info->period,
> +                             HRTIMER_MODE_REL);
> +       else
> +               hrtimer_cancel(&trig_info->timer);
> +
> +       return 0;
> +}
> +
> +static const struct iio_trigger_ops iio_hrtimer_trigger_ops = {
> +       .owner = THIS_MODULE,
> +       .set_trigger_state = iio_trig_hrtimer_set_state,
> +};
> +
> +static struct iio_sw_trigger *iio_trig_hrtimer_probe(const char *name)
> +{
> +       struct iio_hrtimer_info *trig_info;
> +       int ret;
> +
> +       trig_info = kzalloc(sizeof(*trig_info), GFP_KERNEL);
> +       if (!trig_info)
> +               return ERR_PTR(-ENOMEM);
> +
> +       trig_info->swt.trigger = iio_trigger_alloc("%s", name);
> +       if (!trig_info->swt.trigger) {
> +               ret = -ENOMEM;
> +               goto err_free_trig_info;
> +       }
> +
> +       iio_trigger_set_drvdata(trig_info->swt.trigger, trig_info);
> +       trig_info->swt.trigger->ops = &iio_hrtimer_trigger_ops;
> +       trig_info->swt.trigger->dev.groups = iio_hrtimer_attr_groups;
> +
> +       hrtimer_init(&trig_info->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
> +       trig_info->timer.function = iio_hrtimer_trig_handler;
> +
> +       trig_info->sampling_frequency = HRTIMER_DEFAULT_SAMPLING_FREQUENCY;
> +       trig_info->period = ktime_set(0, NSEC_PER_SEC /
> +                                     trig_info->sampling_frequency);
> +
> +       ret = iio_trigger_register(trig_info->swt.trigger);
> +       if (ret)
> +               goto err_free_trigger;
> +
> +       iio_swt_group_init_type_name(&trig_info->swt, name, &iio_hrtimer_type);
> +       return &trig_info->swt;
> +err_free_trigger:
> +       iio_trigger_free(trig_info->swt.trigger);
> +err_free_trig_info:
> +       kfree(trig_info);
> +
> +       return ERR_PTR(ret);
> +}
> +
> +static int iio_trig_hrtimer_remove(struct iio_sw_trigger *swt)
> +{
> +       struct iio_hrtimer_info *trig_info;
> +
> +       trig_info = iio_trigger_get_drvdata(swt->trigger);
> +
> +       iio_trigger_unregister(swt->trigger);
> +
> +       /* cancel the timer after unreg to make sure no one rearms it */
> +       hrtimer_cancel(&trig_info->timer);
> +       iio_trigger_free(swt->trigger);
> +       kfree(trig_info);
> +
> +       return 0;
> +}
> +
> +static const struct iio_sw_trigger_ops iio_trig_hrtimer_ops = {
> +       .probe          = iio_trig_hrtimer_probe,
> +       .remove         = iio_trig_hrtimer_remove,
> +};
> +
> +static struct iio_sw_trigger_type iio_trig_hrtimer = {
> +       .name = "hrtimer",
> +       .owner = THIS_MODULE,
> +       .ops = &iio_trig_hrtimer_ops,
> +};
> +
> +module_iio_sw_trigger_driver(iio_trig_hrtimer);
> +
> +MODULE_AUTHOR("Marten Svanfeldt <marten@intuitiveaerial.com>");
> +MODULE_AUTHOR("Daniel Baluta <daniel.baluta@intel.com>");
> +MODULE_DESCRIPTION("Periodic hrtimer trigger for the IIO subsystem");
> +MODULE_LICENSE("GPL v2");
> --
> 1.9.1
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at  http://www.tux.org/lkml/

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH v9 4/5] iio: trigger: Introduce IIO hrtimer based trigger
@ 2015-10-24  9:10     ` Matt Ranostay
  0 siblings, 0 replies; 12+ messages in thread
From: Matt Ranostay @ 2015-10-24  9:10 UTC (permalink / raw)
  To: Daniel Baluta
  Cc: Jonathan Cameron, jlbec-aKy9MeLSZ9dg9hUCZPvPmw,
	linux-iio-u79uwXL29TY76Z2rM5mHXA,
	linux-fsdevel-u79uwXL29TY76Z2rM5mHXA, Lars-Peter Clausen,
	hch-jcswGhMUV9g, Hartmut Knaack,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	octavian.purdila-ral2JQCrhuEAvxtiuMwx3w,
	pebolle-IWqWACnzNjzz+pZb47iToQ,
	patrick.porlan-ral2JQCrhuEAvxtiuMwx3w,
	adriana.reus-ral2JQCrhuEAvxtiuMwx3w,
	constantin.musca-ral2JQCrhuEAvxtiuMwx3w,
	marten-4zOpVvZifTgX8gGd4fc/mEEOCMrvLtNR,
	cristina.opriceana-Re5JQEeQqe8AvxtiuMwx3w, Peter Meerwald,
	viro-RmSDqhL/yNMiFSDQTTA3OLVCufUGDwFn,
	akpm-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b

Tested-by: Matt Ranostay <matt.ranostay-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>

On Fri, Oct 23, 2015 at 5:32 AM, Daniel Baluta <daniel.baluta-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org> wrote:
> This patch registers a new IIO software trigger interrupt source
> based on high resolution timers.
>
> Notice that if configfs is enabled we create sampling_frequency
> attribute allowing users to change hrtimer period (1/sampling_frequency).
>
> The IIO hrtimer trigger has a long history, this patch is based on
> an older version from Marten and Lars-Peter.
>
> Signed-off-by: Marten Svanfeldt <marten-4zOpVvZifTgX8gGd4fc/mEEOCMrvLtNR@public.gmane.org>
> Signed-off-by: Lars-Peter Clausen <lars-Qo5EllUWu/uELgA04lAiVw@public.gmane.org>
> Signed-off-by: Daniel Baluta <daniel.baluta-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
> ---
>  drivers/iio/trigger/Kconfig            |  10 ++
>  drivers/iio/trigger/Makefile           |   2 +
>  drivers/iio/trigger/iio-trig-hrtimer.c | 193 +++++++++++++++++++++++++++++++++
>  3 files changed, 205 insertions(+)
>  create mode 100644 drivers/iio/trigger/iio-trig-hrtimer.c
>
> diff --git a/drivers/iio/trigger/Kconfig b/drivers/iio/trigger/Kconfig
> index 7999612..519e677 100644
> --- a/drivers/iio/trigger/Kconfig
> +++ b/drivers/iio/trigger/Kconfig
> @@ -5,6 +5,16 @@
>
>  menu "Triggers - standalone"
>
> +config IIO_HRTIMER_TRIGGER
> +       tristate "High resolution timer trigger"
> +       depends on IIO_SW_TRIGGER
> +       help
> +         Provides a frequency based IIO trigger using high resolution
> +         timers as interrupt source.
> +
> +         To compile this driver as a module, choose M here: the
> +         module will be called iio-trig-hrtimer.
> +
>  config IIO_INTERRUPT_TRIGGER
>         tristate "Generic interrupt trigger"
>         help
> diff --git a/drivers/iio/trigger/Makefile b/drivers/iio/trigger/Makefile
> index 0694dae..fe06eb5 100644
> --- a/drivers/iio/trigger/Makefile
> +++ b/drivers/iio/trigger/Makefile
> @@ -3,5 +3,7 @@
>  #
>
>  # When adding new entries keep the list in alphabetical order
> +
> +obj-$(CONFIG_IIO_HRTIMER_TRIGGER) += iio-trig-hrtimer.o
>  obj-$(CONFIG_IIO_INTERRUPT_TRIGGER) += iio-trig-interrupt.o
>  obj-$(CONFIG_IIO_SYSFS_TRIGGER) += iio-trig-sysfs.o
> diff --git a/drivers/iio/trigger/iio-trig-hrtimer.c b/drivers/iio/trigger/iio-trig-hrtimer.c
> new file mode 100644
> index 0000000..5e6d451
> --- /dev/null
> +++ b/drivers/iio/trigger/iio-trig-hrtimer.c
> @@ -0,0 +1,193 @@
> +/**
> + * The industrial I/O periodic hrtimer trigger driver
> + *
> + * Copyright (C) Intuitive Aerial AB
> + * Written by Marten Svanfeldt, marten-4zOpVvZifTgX8gGd4fc/mEEOCMrvLtNR@public.gmane.org
> + * Copyright (C) 2012, Analog Device Inc.
> + *     Author: Lars-Peter Clausen <lars-Qo5EllUWu/uELgA04lAiVw@public.gmane.org>
> + * 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.
> + *
> + */
> +#include <linux/kernel.h>
> +#include <linux/slab.h>
> +#include <linux/hrtimer.h>
> +
> +#include <linux/iio/iio.h>
> +#include <linux/iio/trigger.h>
> +#include <linux/iio/sw_trigger.h>
> +
> +/* default sampling frequency - 100Hz */
> +#define HRTIMER_DEFAULT_SAMPLING_FREQUENCY 100
> +
> +struct iio_hrtimer_info {
> +       struct iio_sw_trigger swt;
> +       struct hrtimer timer;
> +       unsigned long sampling_frequency;
> +       ktime_t period;
> +};
> +
> +static struct config_item_type iio_hrtimer_type = {
> +       .ct_owner = THIS_MODULE,
> +};
> +
> +static
> +ssize_t iio_hrtimer_show_sampling_frequency(struct device *dev,
> +                                           struct device_attribute *attr,
> +                                           char *buf)
> +{
> +       struct iio_trigger *trig = to_iio_trigger(dev);
> +       struct iio_hrtimer_info *info = iio_trigger_get_drvdata(trig);
> +
> +       return snprintf(buf, PAGE_SIZE, "%lu\n", info->sampling_frequency);
> +}
> +
> +static
> +ssize_t iio_hrtimer_store_sampling_frequency(struct device *dev,
> +                                            struct device_attribute *attr,
> +                                            const char *buf, size_t len)
> +{
> +       struct iio_trigger *trig = to_iio_trigger(dev);
> +       struct iio_hrtimer_info *info = iio_trigger_get_drvdata(trig);
> +       unsigned long val;
> +       int ret;
> +
> +       ret = kstrtoul(buf, 10, &val);
> +       if (ret)
> +               return ret;
> +
> +       if (!val || val > NSEC_PER_SEC)
> +               return -EINVAL;
> +
> +       info->sampling_frequency = val;
> +       info->period = ktime_set(0, NSEC_PER_SEC / val);
> +
> +       return len;
> +}
> +
> +static DEVICE_ATTR(sampling_frequency, S_IRUGO | S_IWUSR,
> +                  iio_hrtimer_show_sampling_frequency,
> +                  iio_hrtimer_store_sampling_frequency);
> +
> +static struct attribute *iio_hrtimer_attrs[] = {
> +       &dev_attr_sampling_frequency.attr,
> +       NULL
> +};
> +
> +static const struct attribute_group iio_hrtimer_attr_group = {
> +       .attrs = iio_hrtimer_attrs,
> +};
> +
> +static const struct attribute_group *iio_hrtimer_attr_groups[] = {
> +       &iio_hrtimer_attr_group,
> +       NULL
> +};
> +
> +static enum hrtimer_restart iio_hrtimer_trig_handler(struct hrtimer *timer)
> +{
> +       struct iio_hrtimer_info *info;
> +
> +       info = container_of(timer, struct iio_hrtimer_info, timer);
> +
> +       hrtimer_forward_now(timer, info->period);
> +       iio_trigger_poll(info->swt.trigger);
> +
> +       return HRTIMER_RESTART;
> +}
> +
> +static int iio_trig_hrtimer_set_state(struct iio_trigger *trig, bool state)
> +{
> +       struct iio_hrtimer_info *trig_info;
> +
> +       trig_info = iio_trigger_get_drvdata(trig);
> +
> +       if (state)
> +               hrtimer_start(&trig_info->timer, trig_info->period,
> +                             HRTIMER_MODE_REL);
> +       else
> +               hrtimer_cancel(&trig_info->timer);
> +
> +       return 0;
> +}
> +
> +static const struct iio_trigger_ops iio_hrtimer_trigger_ops = {
> +       .owner = THIS_MODULE,
> +       .set_trigger_state = iio_trig_hrtimer_set_state,
> +};
> +
> +static struct iio_sw_trigger *iio_trig_hrtimer_probe(const char *name)
> +{
> +       struct iio_hrtimer_info *trig_info;
> +       int ret;
> +
> +       trig_info = kzalloc(sizeof(*trig_info), GFP_KERNEL);
> +       if (!trig_info)
> +               return ERR_PTR(-ENOMEM);
> +
> +       trig_info->swt.trigger = iio_trigger_alloc("%s", name);
> +       if (!trig_info->swt.trigger) {
> +               ret = -ENOMEM;
> +               goto err_free_trig_info;
> +       }
> +
> +       iio_trigger_set_drvdata(trig_info->swt.trigger, trig_info);
> +       trig_info->swt.trigger->ops = &iio_hrtimer_trigger_ops;
> +       trig_info->swt.trigger->dev.groups = iio_hrtimer_attr_groups;
> +
> +       hrtimer_init(&trig_info->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
> +       trig_info->timer.function = iio_hrtimer_trig_handler;
> +
> +       trig_info->sampling_frequency = HRTIMER_DEFAULT_SAMPLING_FREQUENCY;
> +       trig_info->period = ktime_set(0, NSEC_PER_SEC /
> +                                     trig_info->sampling_frequency);
> +
> +       ret = iio_trigger_register(trig_info->swt.trigger);
> +       if (ret)
> +               goto err_free_trigger;
> +
> +       iio_swt_group_init_type_name(&trig_info->swt, name, &iio_hrtimer_type);
> +       return &trig_info->swt;
> +err_free_trigger:
> +       iio_trigger_free(trig_info->swt.trigger);
> +err_free_trig_info:
> +       kfree(trig_info);
> +
> +       return ERR_PTR(ret);
> +}
> +
> +static int iio_trig_hrtimer_remove(struct iio_sw_trigger *swt)
> +{
> +       struct iio_hrtimer_info *trig_info;
> +
> +       trig_info = iio_trigger_get_drvdata(swt->trigger);
> +
> +       iio_trigger_unregister(swt->trigger);
> +
> +       /* cancel the timer after unreg to make sure no one rearms it */
> +       hrtimer_cancel(&trig_info->timer);
> +       iio_trigger_free(swt->trigger);
> +       kfree(trig_info);
> +
> +       return 0;
> +}
> +
> +static const struct iio_sw_trigger_ops iio_trig_hrtimer_ops = {
> +       .probe          = iio_trig_hrtimer_probe,
> +       .remove         = iio_trig_hrtimer_remove,
> +};
> +
> +static struct iio_sw_trigger_type iio_trig_hrtimer = {
> +       .name = "hrtimer",
> +       .owner = THIS_MODULE,
> +       .ops = &iio_trig_hrtimer_ops,
> +};
> +
> +module_iio_sw_trigger_driver(iio_trig_hrtimer);
> +
> +MODULE_AUTHOR("Marten Svanfeldt <marten-4zOpVvZifTgX8gGd4fc/mEEOCMrvLtNR@public.gmane.org>");
> +MODULE_AUTHOR("Daniel Baluta <daniel.baluta-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>");
> +MODULE_DESCRIPTION("Periodic hrtimer trigger for the IIO subsystem");
> +MODULE_LICENSE("GPL v2");
> --
> 1.9.1
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at  http://www.tux.org/lkml/

^ permalink raw reply	[flat|nested] 12+ messages in thread

end of thread, other threads:[~2015-10-24  9:10 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-10-23 12:32 [PATCH v9 0/5] Add initial configfs support for IIO Daniel Baluta
2015-10-23 12:32 ` Daniel Baluta
2015-10-23 12:32 ` [PATCH v9 1/5] configfs: Allow dynamic group creation Daniel Baluta
2015-10-23 12:48   ` Christoph Hellwig
2015-10-23 13:08     ` Daniel Baluta
2015-10-23 14:09     ` Daniel Baluta
2015-10-23 12:32 ` [PATCH v9 2/5] iio: core: Introduce IIO configfs support Daniel Baluta
2015-10-23 12:32 ` [PATCH v9 3/5] iio: core: Introduce IIO software triggers Daniel Baluta
2015-10-23 12:32 ` [PATCH v9 4/5] iio: trigger: Introduce IIO hrtimer based trigger Daniel Baluta
2015-10-24  9:10   ` Matt Ranostay
2015-10-24  9:10     ` Matt Ranostay
2015-10-23 12:32 ` [PATCH v9 5/5] iio: Documentation: Add IIO configfs documentation Daniel Baluta

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.