Lars-Peter Clausen <lars@xxxxxxxxxx> wrote: >From: Marten Svanfeldt <marten@xxxxxxxxxxxxxxxxxxx> > >This patch adds a IIO trigger driver which uses a highres timer to >provide a >frequency based trigger. Fine as it stands but same issue arises as we had with userspace trigger still. What are we doing registering a pure software element not associated to any specific hardware via a platform device. Why not do it on userspace asking for one as we do with the sysfs file based trigger? > >Signed-off-by: Lars-Peter Clausen <lars@xxxxxxxxxx> >--- >This patch is based on the version sent by Marten Svanfeldt about a >year ago. > >Changes since v2: > * Use iio_trigger_free to free the trigger > * Set device data in probe >Changes since the inital version: > * Set new timeout in the trigger handler > * Register one trigger device per platform device > * Codestyle cleanups > >Marten can I get your Signed-off-by for this new version? >--- > drivers/staging/iio/trigger/Kconfig | 8 ++ > drivers/staging/iio/trigger/Makefile | 1 + >drivers/staging/iio/trigger/iio-trig-hrtimer.c | 179 >++++++++++++++++++++++++ > 3 files changed, 188 insertions(+) > create mode 100644 drivers/staging/iio/trigger/iio-trig-hrtimer.c > >diff --git a/drivers/staging/iio/trigger/Kconfig >b/drivers/staging/iio/trigger/Kconfig >index b8abf54..7393584 100644 >--- a/drivers/staging/iio/trigger/Kconfig >+++ b/drivers/staging/iio/trigger/Kconfig >@@ -39,4 +39,12 @@ config IIO_BFIN_TMR_TRIGGER > To compile this driver as a module, choose M here: the > module will be called iio-trig-bfin-timer. > >+config IIO_TRIGGER_HRTIMER >+ tristate "Highres timer trigger" >+ help >+ Provides a frequency based IIO trigger using hrtimers. >+ >+ To compile this driver as a module, choose M here: the >+ module will be called iio-trig-hrtimer. >+ > endif # IIO_TRIGGER >diff --git a/drivers/staging/iio/trigger/Makefile >b/drivers/staging/iio/trigger/Makefile >index b088b57..f6f99c2 100644 >--- a/drivers/staging/iio/trigger/Makefile >+++ b/drivers/staging/iio/trigger/Makefile >@@ -6,3 +6,4 @@ obj-$(CONFIG_IIO_PERIODIC_RTC_TRIGGER) += >iio-trig-periodic-rtc.o > obj-$(CONFIG_IIO_GPIO_TRIGGER) += iio-trig-gpio.o > obj-$(CONFIG_IIO_SYSFS_TRIGGER) += iio-trig-sysfs.o > obj-$(CONFIG_IIO_BFIN_TMR_TRIGGER) += iio-trig-bfin-timer.o >+obj-$(CONFIG_IIO_TRIGGER_HRTIMER) += iio-trig-hrtimer.o >diff --git a/drivers/staging/iio/trigger/iio-trig-hrtimer.c >b/drivers/staging/iio/trigger/iio-trig-hrtimer.c >new file mode 100644 >index 0000000..54167fd >--- /dev/null >+++ b/drivers/staging/iio/trigger/iio-trig-hrtimer.c >@@ -0,0 +1,179 @@ >+/** >+ * The industrial I/O periodic hrtimer trigger driver >+ * >+ * Copyright (C) Intuitive Aerial AB >+ * Written by Marten Svanfeldt, marten@xxxxxxxxxxxxxxxxxxx >+ * Copyright (C) 2012, Analog Device Inc. >+ * Author: Lars-Peter Clausen <lars@xxxxxxxxxx> >+ * >+ * 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/platform_device.h> >+#include <linux/kernel.h> >+#include <linux/slab.h> >+#include <linux/hrtimer.h> >+#include "../iio.h" >+#include "../trigger.h" >+ >+struct iio_hrtimer_trig_info { >+ struct iio_trigger *trigger; >+ unsigned int frequency; >+ struct hrtimer timer; >+ ktime_t period; >+}; >+ >+static enum hrtimer_restart iio_trig_hrtimer_trig(struct hrtimer >*timer) >+{ >+ struct iio_hrtimer_trig_info *trig_info; >+ trig_info = container_of(timer, struct iio_hrtimer_trig_info, timer); >+ >+ hrtimer_forward_now(timer, trig_info->period); >+ iio_trigger_poll(trig_info->trigger, 0); >+ >+ return HRTIMER_RESTART; >+} >+ >+static int iio_trig_hrtimer_set_state(struct iio_trigger *trig, bool >state) >+{ >+ struct iio_hrtimer_trig_info *trig_info = trig->private_data; >+ >+ if (trig_info->frequency == 0) >+ return -EINVAL; >+ >+ if (state) { >+ hrtimer_start(&trig_info->timer, trig_info->period, >+ HRTIMER_MODE_REL); >+ } else { >+ hrtimer_cancel(&trig_info->timer); >+ } >+ >+ return 0; >+} >+ >+static ssize_t iio_trig_hrtimer_read_freq(struct device *dev, >+ struct device_attribute *attr, char *buf) >+{ >+ struct iio_trigger *trig = dev_get_drvdata(dev); >+ struct iio_hrtimer_trig_info *trig_info = trig->private_data; >+ >+ return sprintf(buf, "%u\n", trig_info->frequency); >+} >+ >+static ssize_t iio_trig_hrtimer_write_freq(struct device *dev, >+ struct device_attribute *attr, const char *buf, size_t len) >+{ >+ struct iio_trigger *trig = dev_get_drvdata(dev); >+ struct iio_hrtimer_trig_info *trig_info = trig->private_data; >+ unsigned long val; >+ int ret; >+ >+ ret = kstrtoul(buf, 10, &val); >+ if (ret) >+ return ret; >+ >+ if (val > NSEC_PER_SEC) >+ return -EINVAL; >+ >+ trig_info->frequency = val; >+ if (trig_info->frequency != 0) >+ trig_info->period = ktime_set(0, NSEC_PER_SEC / >trig_info->frequency); >+ >+ return len; >+} >+ >+static DEVICE_ATTR(frequency, S_IRUGO | S_IWUSR, >+ iio_trig_hrtimer_read_freq, >+ iio_trig_hrtimer_write_freq); >+ >+static struct attribute *iio_trig_hrtimer_attrs[] = { >+ &dev_attr_frequency.attr, >+ NULL, >+}; >+ >+static const struct attribute_group iio_trig_hrtimer_attr_group = { >+ .attrs = iio_trig_hrtimer_attrs, >+}; >+ >+static const struct attribute_group *iio_trig_hrtimer_attr_groups[] = >{ >+ &iio_trig_hrtimer_attr_group, >+ NULL >+}; >+ >+static const struct iio_trigger_ops iio_hrtimer_trigger_ops = { >+ .owner = THIS_MODULE, >+ .set_trigger_state = iio_trig_hrtimer_set_state, >+}; >+ >+static int __devinit iio_trig_hrtimer_probe(struct platform_device >*pdev) >+{ >+ struct iio_hrtimer_trig_info *trig_info; >+ struct iio_trigger *trig; >+ const char *name; >+ int ret; >+ >+ trig_info = devm_kzalloc(&pdev->dev, sizeof(*trig_info), GFP_KERNEL); >+ if (!trig_info) >+ return -ENOMEM; >+ >+ name = pdev->dev.platform_data; >+ >+ if (name != NULL) >+ trig = iio_allocate_trigger("hrtimer%s", name); >+ else >+ trig = iio_allocate_trigger("hrtimer%d", pdev->id); >+ >+ if (!trig) >+ return -ENOMEM; >+ >+ trig_info->trigger = trig; >+ trig->private_data = trig_info; >+ trig->ops = &iio_hrtimer_trigger_ops; >+ trig->dev.groups = iio_trig_hrtimer_attr_groups; >+ trig->dev.parent = &pdev->dev; >+ >+ hrtimer_init(&trig_info->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); >+ trig_info->timer.function = iio_trig_hrtimer_trig; >+ >+ ret = iio_trigger_register(trig); >+ if (ret) >+ goto err_free_trigger; >+ >+ platform_set_drvdata(pdev, trig_info); >+ >+ return 0; >+err_free_trigger: >+ iio_free_trigger(trig); >+ >+ return ret; >+} >+ >+static int __devexit iio_trig_hrtimer_remove(struct platform_device >*pdev) >+{ >+ struct iio_hrtimer_trig_info *trig_info = platform_get_drvdata(pdev); >+ struct iio_trigger *trig = trig_info->trigger; >+ >+ iio_trigger_unregister(trig); >+ hrtimer_cancel(&trig_info->timer); >+ iio_free_trigger(trig); >+ >+ return 0; >+} >+ >+static struct platform_driver iio_trig_hrtimer_driver = { >+ .driver = { >+ .name = "iio-trigger-hrtimer", >+ .owner = THIS_MODULE >+ }, >+ .probe = iio_trig_hrtimer_probe, >+ .remove = __devexit_p(iio_trig_hrtimer_remove), >+}; >+module_platform_driver(iio_trig_hrtimer_driver); >+ >+MODULE_AUTHOR("Marten Svanfeldt <marten@xxxxxxxxxxxxxxxxxxx>"); >+MODULE_DESCRIPTION("Periodic hrtimer trigger for the IIO subsystem"); >+MODULE_LICENSE("GPL v2"); >+MODULE_ALIAS("platform:iio-trigger-hrtimer"); >-- >1.7.9.5 > >-- >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 -- Sent from my Android phone with K-9 Mail. Please excuse my brevity. -- 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