Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755074AbbHQMqK (ORCPT ); Mon, 17 Aug 2015 08:46:10 -0400 Received: from mail-wi0-f182.google.com ([209.85.212.182]:34759 "EHLO mail-wi0-f182.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753131AbbHQMqH (ORCPT ); Mon, 17 Aug 2015 08:46:07 -0400 Message-ID: <55D1D786.2010407@cogentembedded.com> Date: Mon, 17 Aug 2015 15:45:58 +0300 From: Vladimir Barinov User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:31.0) Gecko/20100101 Thunderbird/31.8.0 MIME-Version: 1.0 To: Daniel Baluta , jic23@kernel.org, jlbec@evilplan.org, linux-iio@vger.kernel.org, linux-fsdevel@vger.kernel.org CC: lars@metafoo.de, knaack.h@gmx.de, linux-kernel@vger.kernel.org, octavian.purdila@intel.com, pebolle@tiscali.nl, patrick.porlan@intel.com, adriana.reus@intel.com, constantin.musca@intel.com, marten@intuitiveaerial.com, cristina.opriceana@gmail.com, pmeerw@pmeerw.net, hch@lst.de, viro@zeniv.linux.org.uk, akpm@linux-foundation.org Subject: Re: [PATCH v7 4/5] iio: trigger: Introduce IIO hrtimer based trigger References: <1439246562-17515-1-git-send-email-daniel.baluta@intel.com> <1439246562-17515-5-git-send-email-daniel.baluta@intel.com> In-Reply-To: <1439246562-17515-5-git-send-email-daniel.baluta@intel.com> Content-Type: text/plain; charset=windows-1252; format=flowed Content-Transfer-Encoding: 7bit Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 8355 Lines: 273 Hello Daniel, I've verified that your hrtimer trigger works. I have minor suggestions. Will not it be useful to have ability to stop/start hrtimer polling not only during attach/detach trigger. f.e. writing 0 to sampling_frequency will hrtimer_cancel and writing any valid frequency will hrtimer_start. Regards, Vladimir On 11.08.2015 01:42, Daniel Baluta 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 > Signed-off-by: Lars-Peter Clausen > Signed-off-by: Daniel Baluta > --- > 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..4505281 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" > + select 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..4631c7a > --- /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 > + * 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 > +#include > +#include > + > +#include > +#include > +#include > + > +/* 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; > +} > + > +const struct iio_sw_trigger_ops iio_trig_hrtimer_ops = { > + .probe = iio_trig_hrtimer_probe, > + .remove = iio_trig_hrtimer_remove, > +}; > + > +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 "); > +MODULE_AUTHOR("Daniel Baluta "); > +MODULE_DESCRIPTION("Periodic hrtimer trigger for the IIO subsystem"); > +MODULE_LICENSE("GPL v2"); -- 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/