* High frequency software trigger @ 2011-03-04 7:26 Marten Svanfeldt 2011-03-04 9:19 ` Hennerich, Michael 0 siblings, 1 reply; 9+ messages in thread From: Marten Svanfeldt @ 2011-03-04 7:26 UTC (permalink / raw) To: linux-iio Hi, I have recently begun looking at utilizing iio for the input part of a robotics system but have some doubts about its usability for which I would like your comments. Today we have (in our embedded system) a number of custom written drivers interfacing SPI attached accelerometers and AD converters, utilizing hrtimers for software triggering of sampling at 50 to 250 Hz. Herein lays my current question, has anyone used the IIO system with these type of sampling rates? The RTC based trigger seems to only give second or higher intervals. I will be looking at converting our special drivers to be acceptable for upstream submission, same for a hrtimers based trigger, should that be a good idea. Best regards Marten Svanfeldt ^ permalink raw reply [flat|nested] 9+ messages in thread
* RE: High frequency software trigger 2011-03-04 7:26 High frequency software trigger Marten Svanfeldt @ 2011-03-04 9:19 ` Hennerich, Michael 2011-03-04 10:32 ` Marten Svanfeldt 0 siblings, 1 reply; 9+ messages in thread From: Hennerich, Michael @ 2011-03-04 9:19 UTC (permalink / raw) To: Marten Svanfeldt, linux-iio@vger.kernel.org Marten Svanfeldt wrote on 2011-03-04: > Hi, > > I have recently begun looking at utilizing iio for the input part of a > robotics system but have some doubts about its usability for which I > would like your comments. > > Today we have (in our embedded system) a number of custom written > drivers interfacing SPI attached accelerometers and AD converters, > utilizing hrtimers for software triggering of sampling at 50 to 250 Hz. > Herein lays my current question, has anyone used the IIO system with > these type of sampling rates? The RTC based trigger seems to only give > second or higher intervals. > > I will be looking at converting our special drivers to be acceptable > for upstream submission, same for a hrtimers based trigger, should > that be a good idea. > > Best regards > Marten Svanfeldt I recently submitted a trigger source driver that utilizes Blackfin hardware timer. http://wiki.analog.com/software/linux/docs/iio/iio-trig-bfin-timer Not sure what your platform is, but there might be similar peripherals, that can generate sub second cyclic interrupts. I successfully used it on a fast Blackfin processor at frequencies of 10kHz and above, with this simple demo application. http://wiki.analog.com/software/linux/docs/iio/iio_netscope Greetings, Michael -- Analog Devices GmbH Wilhelm-Wagenfeld-Str. 6 80807 Muenchen Sitz der Gesellschaft: Muenchen; Registergericht: Muenchen HRB 40368; Geschaeftsfuehrer:Dr.Carsten Suckrow, Thomas Wessel, William A. Martin, Margaret Seif ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: High frequency software trigger 2011-03-04 9:19 ` Hennerich, Michael @ 2011-03-04 10:32 ` Marten Svanfeldt 2011-03-04 11:10 ` Jonathan Cameron 0 siblings, 1 reply; 9+ messages in thread From: Marten Svanfeldt @ 2011-03-04 10:32 UTC (permalink / raw) To: Hennerich, Michael; +Cc: linux-iio@vger.kernel.org On 2011-03-04 17:19, Hennerich, Michael wrote: > > I recently submitted a trigger source driver that utilizes Blackfin hardware timer. > > http://wiki.analog.com/software/linux/docs/iio/iio-trig-bfin-timer Thank you, this had passed me by. Looking at the source, it seems that a hrtimer based trigger would be something similar, except not tied to any specific platform. > > Not sure what your platform is, but there might be similar peripherals, > that can generate sub second cyclic interrupts. The platform in question is an TI OMAP3 (3530) based system, but my goal would be to utilize hrtimers as they are not tied to a specific platform. They are supposed to work on our target platform, but I haven't had time to test them extensively yet. > I successfully used it on a fast Blackfin processor at frequencies of 10kHz and above, > with this simple demo application. > > http://wiki.analog.com/software/linux/docs/iio/iio_netscope 10kHz sounds reassuring, in my case it is about 250Hz max, but some 13 or so channels. Did you get any idea where the limitations lies in terms of system load etc? Of course this depends on the exact setup, just trying to find all possible sides of moving our code over to be IIO-based. Regards Marten Svanfeldt ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: High frequency software trigger 2011-03-04 10:32 ` Marten Svanfeldt @ 2011-03-04 11:10 ` Jonathan Cameron 2011-03-07 5:49 ` Marten Svanfeldt ` (2 more replies) 0 siblings, 3 replies; 9+ messages in thread From: Jonathan Cameron @ 2011-03-04 11:10 UTC (permalink / raw) To: Marten Svanfeldt; +Cc: Hennerich, Michael, linux-iio@vger.kernel.org Hi Marten, >> I recently submitted a trigger source driver that utilizes Blackfin hardware timer. >> >> http://wiki.analog.com/software/linux/docs/iio/iio-trig-bfin-timer > > Thank you, this had passed me by. Looking at the source, it seems > that a hrtimer based trigger would be something similar, except not > tied to any specific platform. Agreed. The rtc trigger is a silly historical relic from the pxa platform I use which does do higher frequency periodic rtc tics. I also have a driver for that which effectively does the same as Michaels blackfin one, but via the rtc interface (gives me 7 additional rtcs). A generic hrtimer approach is something I've thought about from time to time but never gotten round to actually writing! Hence I'd certainly be interested in your generic driver. >> >> Not sure what your platform is, but there might be similar peripherals, >> that can generate sub second cyclic interrupts. > The platform in question is an TI OMAP3 (3530) based system, but my > goal would be to utilize hrtimers as they are not tied to a specific > platform. They are supposed to work on our target platform, but I > haven't had time to test them extensively yet. The advantage of using specific timers originally was the simplicity of setting them up. They look very much like an interrupt coming off the sensor hence can be set up then left alone. > >> I successfully used it on a fast Blackfin processor at frequencies of 10kHz and above, >> with this simple demo application. >> >> http://wiki.analog.com/software/linux/docs/iio/iio_netscope > 10kHz sounds reassuring, in my case it is about 250Hz max, but some > 13 or so channels. Did you get any idea where the limitations lies in > terms of system load etc? Of course this depends on the exact setup, > just trying to find all possible sides of moving our code over to be > IIO-based. I'm quite happily doing 4 channels off the periodic rtc at 1Khz on a pxa271. Things got a bit choppy in timing when we went to 2Khz but it works well enough. The uneven timing had definite spikes so I suspect other things were hogging the processor from time to time. I should probably revisit these tests and see if I can pin down exactly what is causing the issue (that was about 2 years ago so it may well have gone away!) I'm only superficially familiar with the abilities of hrtimers. Perhaps you could post your current code as an RFC so we can get an idea of exactly how this would work? Thanks, Jonathan ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: High frequency software trigger 2011-03-04 11:10 ` Jonathan Cameron @ 2011-03-07 5:49 ` Marten Svanfeldt 2011-03-09 14:00 ` [RFC] IIO: trigger: New hrtimer based trigger driver Marten Svanfeldt 2011-03-09 14:00 ` [PATCH] " Marten Svanfeldt 2 siblings, 0 replies; 9+ messages in thread From: Marten Svanfeldt @ 2011-03-07 5:49 UTC (permalink / raw) To: Jonathan Cameron; +Cc: Hennerich, Michael, linux-iio@vger.kernel.org On 2011-03-04 19:10, Jonathan Cameron wrote: > I'm only superficially familiar with the abilities of hrtimers. > Perhaps you could post your current code as an RFC so we can get an idea of exactly > how this would work? Right now my work is a mix of driver interfacing code and triggering, being the result of hacking away during my thesis work. I will try to write a cleaner hrtimers based trigger during the next week(s) and send it for review, with the limit of not having access to our target platform right now so testing will be limited. Regards Marten Svanfeldt ^ permalink raw reply [flat|nested] 9+ messages in thread
* [RFC] IIO: trigger: New hrtimer based trigger driver 2011-03-04 11:10 ` Jonathan Cameron 2011-03-07 5:49 ` Marten Svanfeldt @ 2011-03-09 14:00 ` Marten Svanfeldt 2011-03-09 14:00 ` [PATCH] " Marten Svanfeldt 2 siblings, 0 replies; 9+ messages in thread From: Marten Svanfeldt @ 2011-03-09 14:00 UTC (permalink / raw) To: linux-iio; +Cc: jic23, michael.hennerich I took the time to extract the hrtimer bits of my ugly driver and transplanted it to a base of the rtc trigger and blackfin trigger. Consider this driver an early RFC, it has been compile tested for x86 and ARM, but I haven't had any possibility to run it as I don't have access to our hardware platform right now. Regards Marten Svanfeldt ^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH] IIO: trigger: New hrtimer based trigger driver 2011-03-04 11:10 ` Jonathan Cameron 2011-03-07 5:49 ` Marten Svanfeldt 2011-03-09 14:00 ` [RFC] IIO: trigger: New hrtimer based trigger driver Marten Svanfeldt @ 2011-03-09 14:00 ` Marten Svanfeldt 2011-03-09 19:31 ` Jonathan Cameron 2 siblings, 1 reply; 9+ messages in thread From: Marten Svanfeldt @ 2011-03-09 14:00 UTC (permalink / raw) To: linux-iio; +Cc: jic23, michael.hennerich, Marten Svanfeldt This driver provide a way to utilize hrtimer as an IIO trigger source. Signed-off-by: Marten Svanfeldt <marten@intuitiveaerial.com> --- drivers/staging/iio/trigger/Kconfig | 6 + drivers/staging/iio/trigger/Makefile | 2 + drivers/staging/iio/trigger/iio-trig-hrtimer.c | 208 ++++++++++++++++++++++++ 3 files changed, 216 insertions(+), 0 deletions(-) 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 d842a58..35d676a 100644 --- a/drivers/staging/iio/trigger/Kconfig +++ b/drivers/staging/iio/trigger/Kconfig @@ -18,4 +18,10 @@ config IIO_GPIO_TRIGGER help Provides support for using GPIO pins as IIO triggers. +config IIO_HRTIMER_TRIGGER + tristate "hrtimer trigger" + help + Provides support for using hrtimer as periodic IIO + trigger. + endif # IIO_TRIGGER diff --git a/drivers/staging/iio/trigger/Makefile b/drivers/staging/iio/trigger/Makefile index 10aeca5..d178c66 100644 --- a/drivers/staging/iio/trigger/Makefile +++ b/drivers/staging/iio/trigger/Makefile @@ -4,3 +4,5 @@ obj-$(CONFIG_IIO_PERIODIC_RTC_TRIGGER) += iio-trig-periodic-rtc.o obj-$(CONFIG_IIO_GPIO_TRIGGER) += iio-trig-gpio.o +obj-$(CONFIG_IIO_HRTIMER_TRIGGER) += 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..16b5af5 --- /dev/null +++ b/drivers/staging/iio/trigger/iio-trig-hrtimer.c @@ -0,0 +1,208 @@ +/** + * The industrial I/O periodic hrtimer trigger driver + * + * Copyright (C) Intuitive Aerial AB + * Written by Marten Svanfeldt, marten@intuitiveaerial.com + * + * 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" + +static LIST_HEAD(iio_hrtimer_trigger_list); + +struct iio_hrtimer_trig_info { + struct iio_trigger *trigger; + unsigned int frequency; + struct hrtimer timer; +}; + +static enum hrtimer_restart iio_trig_hrtimer_trig(struct hrtimer *timer) +{ + struct iio_hrtimer_trig_info *trig_info = container_of(timer, struct iio_hrtimer_trig_info, timer); + + 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, + ktime_set(0, NSEC_PER_SEC/trig_info->frequency), + 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 = strict_strtoul(buf, 10, &val); + if(ret) + goto error_ret; + + trig_info->frequency = val; + + return len; + +error_ret: + return ret; +} + +static IIO_TRIGGER_NAME_ATTR; +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_name.attr, + &dev_attr_frequency.attr, + NULL, +}; + +static const struct attribute_group iio_trig_hrtimer_attr_group = { + .attrs = iio_trig_hrtimer_attrs, +}; + +static int iio_trig_hrtimer_probe(struct platform_device *dev) +{ + char **pdata = dev->dev.platform_data; + struct iio_hrtimer_trig_info *trig_info; + struct iio_trigger *trig, *trig2; + + int i, ret; + + for(i = 0;; i++) { + if(pdata[i] == NULL) + break; + + trig = iio_allocate_trigger(); + if(!trig) { + ret = -ENOMEM; + goto err_free_completed_reg; + } + list_add(&trig->alloc_list, &iio_hrtimer_trigger_list); + + trig_info = kzalloc(sizeof(struct iio_hrtimer_trig_info), GFP_KERNEL); + if(!trig_info) { + ret = -ENOMEM; + goto err_put_trigger; + } + trig_info->trigger = trig; + trig->private_data = trig_info; + trig->owner = THIS_MODULE; + trig->set_trigger_state = &iio_trig_hrtimer_set_state; + trig->name = kasprintf(GFP_KERNEL, "hrtimer%s", pdata[i]); + if(!trig->name) { + ret = -ENOMEM; + goto err_free_trig_info; + } + + // Setup a hrtimer + 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_name; + } + + return 0; +err_free_name: + kfree(trig->name); +err_free_trig_info: + kfree(trig_info); +err_put_trigger: + list_del(&trig->alloc_list); + iio_put_trigger(trig); +err_free_completed_reg: + list_for_each_entry_safe(trig, + trig2, + &iio_hrtimer_trigger_list, + alloc_list) { + trig_info = trig->private_data; + kfree(trig->name); + kfree(trig_info); + iio_trigger_unregister(trig); + } + + return ret; +} + +static int iio_trig_hrtimer_remove(struct platform_device *dev) +{ + struct iio_trigger *trig, *trig2; + struct iio_hrtimer_trig_info *trig_info; + + list_for_each_entry_safe(trig, + trig2, + &iio_hrtimer_trigger_list, + alloc_list) { + trig_info = trig->private_data; + hrtimer_cancel(&trig_info->timer); + kfree(trig->name); + kfree(trig_info); + iio_trigger_unregister(trig); + } + + return 0; +} + +static struct platform_driver iio_trig_hrtimer_driver = { + .driver = { + .name = "iio_hrtimer_trigger", + .owner = THIS_MODULE + }, + .probe = iio_trig_hrtimer_probe, + .remove = iio_trig_hrtimer_remove, +}; + +static int __init iio_trig_hrtimer_init(void) +{ + return platform_driver_register(&iio_trig_hrtimer_driver); +} + +static void __exit iio_trig_hrtimer_exit(void) +{ + return platform_driver_unregister(&iio_trig_hrtimer_driver); +} + +module_init(iio_trig_hrtimer_init); +module_exit(iio_trig_hrtimer_exit); +MODULE_AUTHOR("Marten Svanfeldt <marten@intuitiveaerial.com>"); +MODULE_DESCRIPTION("Periodic hrtimer trigger for the iio subsystem"); +MODULE_LICENSE("GPL v2"); +MODULE_ALIAS("platofrm:iio-trig-hrtimer"); + -- 1.7.0.4 ^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: [PATCH] IIO: trigger: New hrtimer based trigger driver 2011-03-09 14:00 ` [PATCH] " Marten Svanfeldt @ 2011-03-09 19:31 ` Jonathan Cameron 2011-03-10 2:19 ` Marten Svanfeldt 0 siblings, 1 reply; 9+ messages in thread From: Jonathan Cameron @ 2011-03-09 19:31 UTC (permalink / raw) To: Marten Svanfeldt; +Cc: linux-iio, michael.hennerich On 03/09/11 14:00, Marten Svanfeldt wrote: > This driver provide a way to utilize hrtimer as an IIO trigger source. Looks quite nice. Some comments inline. I know this is only a quick untested example, but as I was reading anyway... Obviously run checkpatch over it at some point. Otherwise, nice clean little trigger driver. After cleanup and testing I would be happy to see this in IIO. Never realised it would be this simple :) Thanks. Jonathan > > Signed-off-by: Marten Svanfeldt <marten@intuitiveaerial.com> > --- > drivers/staging/iio/trigger/Kconfig | 6 + > drivers/staging/iio/trigger/Makefile | 2 + > drivers/staging/iio/trigger/iio-trig-hrtimer.c | 208 ++++++++++++++++++++++++ > 3 files changed, 216 insertions(+), 0 deletions(-) > 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 d842a58..35d676a 100644 > --- a/drivers/staging/iio/trigger/Kconfig > +++ b/drivers/staging/iio/trigger/Kconfig > @@ -18,4 +18,10 @@ config IIO_GPIO_TRIGGER > help > Provides support for using GPIO pins as IIO triggers. > > +config IIO_HRTIMER_TRIGGER > + tristate "hrtimer trigger" Is it worth spelling out high resolution as not every person who builds a kernel will know what hr stands for? > + help > + Provides support for using hrtimer as periodic IIO > + trigger. > + > endif # IIO_TRIGGER > diff --git a/drivers/staging/iio/trigger/Makefile b/drivers/staging/iio/trigger/Makefile > index 10aeca5..d178c66 100644 > --- a/drivers/staging/iio/trigger/Makefile > +++ b/drivers/staging/iio/trigger/Makefile > @@ -4,3 +4,5 @@ > > obj-$(CONFIG_IIO_PERIODIC_RTC_TRIGGER) += iio-trig-periodic-rtc.o > obj-$(CONFIG_IIO_GPIO_TRIGGER) += iio-trig-gpio.o > +obj-$(CONFIG_IIO_HRTIMER_TRIGGER) += iio-trig-hrtimer.o Oops, I ought to resort these into alphabetical order at some point! > + > 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..16b5af5 > --- /dev/null > +++ b/drivers/staging/iio/trigger/iio-trig-hrtimer.c > @@ -0,0 +1,208 @@ > +/** > + * The industrial I/O periodic hrtimer trigger driver > + * > + * Copyright (C) Intuitive Aerial AB > + * Written by Marten Svanfeldt, marten@intuitiveaerial.com > + * > + * 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" > + > +static LIST_HEAD(iio_hrtimer_trigger_list); > + > +struct iio_hrtimer_trig_info { hmm.. I should rework the trigger allocation code to allow for this structure to be directly embedded in another. Would make things a bit cleaner for you and probably a number of other users. > + struct iio_trigger *trigger; > + unsigned int frequency; > + struct hrtimer timer; > +}; > + > +static enum hrtimer_restart iio_trig_hrtimer_trig(struct hrtimer *timer) > +{ > + struct iio_hrtimer_trig_info *trig_info = container_of(timer, struct iio_hrtimer_trig_info, timer); > + > + iio_trigger_poll(trig_info->trigger, 0); Out of curiosity, how suceptible to drift is this? I guess the timer doesn't take into account the amout of time this function takes, e.g how late are we by the time the timer is restarted? > + 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, > + ktime_set(0, NSEC_PER_SEC/trig_info->frequency), > + 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 = strict_strtoul(buf, 10, &val); > + if(ret) > + goto error_ret; > + > + trig_info->frequency = val; Only applied on trigger being stopped and restarted I think? Maybe return -EBUSY if the trigger is running to make this obvious to userspace. > + > + return len; > + > +error_ret: > + return ret; > +} > + > +static IIO_TRIGGER_NAME_ATTR; > +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_name.attr, > + &dev_attr_frequency.attr, > + NULL, > +}; > + > +static const struct attribute_group iio_trig_hrtimer_attr_group = { > + .attrs = iio_trig_hrtimer_attrs, > +}; > + > +static int iio_trig_hrtimer_probe(struct platform_device *dev) > +{ > + char **pdata = dev->dev.platform_data; > + struct iio_hrtimer_trig_info *trig_info; > + struct iio_trigger *trig, *trig2; > + > + int i, ret; > + while(pdata != NULL) then increment pdata pointer? > + for(i = 0;; i++) { > + if(pdata[i] == NULL) > + break; > + > + trig = iio_allocate_trigger(); > + if(!trig) { > + ret = -ENOMEM; > + goto err_free_completed_reg; > + } > + list_add(&trig->alloc_list, &iio_hrtimer_trigger_list); > + > + trig_info = kzalloc(sizeof(struct iio_hrtimer_trig_info), GFP_KERNEL); > + if(!trig_info) { > + ret = -ENOMEM; > + goto err_put_trigger; > + } > + trig_info->trigger = trig; > + trig->private_data = trig_info; > + trig->owner = THIS_MODULE; > + trig->set_trigger_state = &iio_trig_hrtimer_set_state; > + trig->name = kasprintf(GFP_KERNEL, "hrtimer%s", pdata[i]); > + if(!trig->name) { > + ret = -ENOMEM; > + goto err_free_trig_info; > + } > + > + // Setup a hrtimer > + 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_name; > + } > + > + return 0; > +err_free_name: > + kfree(trig->name); > +err_free_trig_info: > + kfree(trig_info); > +err_put_trigger: > + list_del(&trig->alloc_list); > + iio_put_trigger(trig); > +err_free_completed_reg: > + list_for_each_entry_safe(trig, > + trig2, > + &iio_hrtimer_trigger_list, > + alloc_list) { > + trig_info = trig->private_data; > + kfree(trig->name); > + kfree(trig_info); > + iio_trigger_unregister(trig); > + } > + > + return ret; > +} > + > +static int iio_trig_hrtimer_remove(struct platform_device *dev) > +{ > + struct iio_trigger *trig, *trig2; > + struct iio_hrtimer_trig_info *trig_info; > + > + list_for_each_entry_safe(trig, > + trig2, > + &iio_hrtimer_trigger_list, > + alloc_list) { > + trig_info = trig->private_data; > + hrtimer_cancel(&trig_info->timer); > + kfree(trig->name); > + kfree(trig_info); > + iio_trigger_unregister(trig); > + } > + > + return 0; > +} > + > +static struct platform_driver iio_trig_hrtimer_driver = { > + .driver = { > + .name = "iio_hrtimer_trigger", > + .owner = THIS_MODULE > + }, > + .probe = iio_trig_hrtimer_probe, > + .remove = iio_trig_hrtimer_remove, > +}; > + > +static int __init iio_trig_hrtimer_init(void) > +{ > + return platform_driver_register(&iio_trig_hrtimer_driver); > +} > + > +static void __exit iio_trig_hrtimer_exit(void) > +{ > + return platform_driver_unregister(&iio_trig_hrtimer_driver); > +} > + > +module_init(iio_trig_hrtimer_init); > +module_exit(iio_trig_hrtimer_exit); > +MODULE_AUTHOR("Marten Svanfeldt <marten@intuitiveaerial.com>"); > +MODULE_DESCRIPTION("Periodic hrtimer trigger for the iio subsystem"); > +MODULE_LICENSE("GPL v2"); > +MODULE_ALIAS("platofrm:iio-trig-hrtimer"); > + ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH] IIO: trigger: New hrtimer based trigger driver 2011-03-09 19:31 ` Jonathan Cameron @ 2011-03-10 2:19 ` Marten Svanfeldt 0 siblings, 0 replies; 9+ messages in thread From: Marten Svanfeldt @ 2011-03-10 2:19 UTC (permalink / raw) To: Jonathan Cameron; +Cc: linux-iio, michael.hennerich On 2011-03-10 03:31, Jonathan Cameron wrote: > Obviously run checkpatch over it at some point. Will be done. > Otherwise, nice clean little trigger driver. After cleanup and > testing I would be happy to see this in IIO. Never realised it > would be this simple :) Looking over your comments I realized I forgot to pull over one part (or rather, thought I didn't need it but I do), which makes it a little bit more complex.. hrtimer callbacks are sent in hardirq context, which was OK in my driver, but as some IIO things involve SPI/I2C communications etc it needs to be moved over to a softirq setup. I will look into getting this fixed for a v2 patch. >> +static enum hrtimer_restart iio_trig_hrtimer_trig(struct hrtimer *timer) >> +{ >> + struct iio_hrtimer_trig_info *trig_info = container_of(timer, struct iio_hrtimer_trig_info, timer); >> + >> + iio_trigger_poll(trig_info->trigger, 0); > Out of curiosity, how suceptible to drift is this? I guess the timer doesn't take > into account the amout of time this function takes, e.g how late are we by the time > the timer is restarted? This function is missing one line that updates the expiry time of the timer.. and the new expiry time is calculated based on the old time which means it should not drift at all. It can however "miss ticks" if the trigger poll takes longer than the interval. >> + >> + trig_info->frequency = val; > Only applied on trigger being stopped and restarted I think? > Maybe return -EBUSY if the trigger is running to make this > obvious to userspace. Yes, I was unsure how to handle this properly.. I think I can make it update it properly if it is running though. I'll have a v2 patch out in a couple of days, still untested as seems to be a few weeks before I get the second spin of our board on which I can run it. Regards Marten Svanfeldt ^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2011-03-10 2:19 UTC | newest] Thread overview: 9+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2011-03-04 7:26 High frequency software trigger Marten Svanfeldt 2011-03-04 9:19 ` Hennerich, Michael 2011-03-04 10:32 ` Marten Svanfeldt 2011-03-04 11:10 ` Jonathan Cameron 2011-03-07 5:49 ` Marten Svanfeldt 2011-03-09 14:00 ` [RFC] IIO: trigger: New hrtimer based trigger driver Marten Svanfeldt 2011-03-09 14:00 ` [PATCH] " Marten Svanfeldt 2011-03-09 19:31 ` Jonathan Cameron 2011-03-10 2:19 ` Marten Svanfeldt
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox