From: Jonathan Cameron <jic23@kernel.org>
To: Gregor Boirie <gregor.boirie@parrot.com>, linux-iio@vger.kernel.org
Cc: lars@metafoo.de
Subject: Re: [RFC PATCH v1 1/3] iio:core: timestamping clock selection support
Date: Sat, 13 Feb 2016 14:14:33 +0000 [thread overview]
Message-ID: <56BF3A49.1000908@kernel.org> (raw)
In-Reply-To: <3e2d224ccd59ecba141e1320e804c674eb61c686.1455184829.git.gregor.boirie@parrot.com>
On 11/02/16 10:04, Gregor Boirie wrote:
> Adds a new per-device sysfs attribute "clockid" to allow userspace to select a
> particular POSIX clock for buffered samples and events timestamping.
>
> When read, the attribute file returns a stringifi'ed clockid_t matching the
> currently selected clock.
> Writing a stringifi'ed clockid_t to the attribute file will select the
> corresponding clock for the device.
>
> Following clocks, as listed in clock_gettime(2), are supported: CLOCK_REALTIME,
> CLOCK_MONOTONIC, CLOCK_MONOTONIC_RAW, CLOCK_REALTIME_COARSE,
> CLOCK_MONOTONIC_COARSE, CLOCK_BOOTTIME and CLOCK_TAI.
>
> Signed-off-by: Gregor Boirie <gregor.boirie@parrot.com>
> ---
> Documentation/ABI/testing/sysfs-bus-iio | 7 +++
> Documentation/DocBook/iio.tmpl | 2 +-
> drivers/iio/iio_core.h | 3 +
> drivers/iio/industrialio-core.c | 107 ++++++++++++++++++++++++++++++--
> drivers/iio/industrialio-event.c | 19 +++++-
> drivers/iio/industrialio-trigger.c | 2 +-
> include/linux/iio/iio.h | 10 +--
> 7 files changed, 134 insertions(+), 16 deletions(-)
>
> diff --git a/Documentation/ABI/testing/sysfs-bus-iio b/Documentation/ABI/testing/sysfs-bus-iio
> index 3c66248..4602006 100644
> --- a/Documentation/ABI/testing/sysfs-bus-iio
> +++ b/Documentation/ABI/testing/sysfs-bus-iio
> @@ -32,6 +32,13 @@ Description:
> Description of the physical chip / device for device X.
> Typically a part number.
>
> +What: /sys/bus/iio/devices/iio:deviceX/clockid
> +KernelVersion: 4.5
> +Contact: linux-iio@vger.kernel.org
> +Description:
> + Identifier (clockid_t) of current posix clock used to timestamp
> + buffered samples and events for device X.
As it's been written into a sysfs attribute I'd normally prefer to see a
descriptive string for something like this. What do others think?
clockid_t is clearly fixed abi so this makes reasonable sense. Are there
other sysfs attributes to select the clock already present elsewhere in the
kernel?
> +
> What: /sys/bus/iio/devices/iio:deviceX/sampling_frequency
> What: /sys/bus/iio/devices/iio:deviceX/buffer/sampling_frequency
> What: /sys/bus/iio/devices/triggerX/sampling_frequency
> diff --git a/Documentation/DocBook/iio.tmpl b/Documentation/DocBook/iio.tmpl
> index f525bf5..df47dd4 100644
> --- a/Documentation/DocBook/iio.tmpl
> +++ b/Documentation/DocBook/iio.tmpl
> @@ -594,7 +594,7 @@
>
> irqreturn_t sensor_iio_pollfunc(int irq, void *p)
> {
> - pf->timestamp = iio_get_time_ns();
> + pf->timestamp = iio_get_time_ns((struct indio_dev*) p);
> return IRQ_WAKE_THREAD;
> }
>
> diff --git a/drivers/iio/iio_core.h b/drivers/iio/iio_core.h
> index 3598835..a07d2ec 100644
> --- a/drivers/iio/iio_core.h
> +++ b/drivers/iio/iio_core.h
> @@ -79,4 +79,7 @@ void iio_device_unregister_eventset(struct iio_dev *indio_dev);
> void iio_device_wakeup_eventset(struct iio_dev *indio_dev);
> int iio_event_getfd(struct iio_dev *indio_dev);
>
> +struct iio_event_interface;
> +bool iio_event_enabled(const struct iio_event_interface* ev_int);
> +
> #endif
> diff --git a/drivers/iio/industrialio-core.c b/drivers/iio/industrialio-core.c
> index 70cb7eb..97bdb95 100644
> --- a/drivers/iio/industrialio-core.c
> +++ b/drivers/iio/industrialio-core.c
> @@ -174,6 +174,44 @@ ssize_t iio_read_const_attr(struct device *dev,
> }
> EXPORT_SYMBOL(iio_read_const_attr);
>
> +/**
> + * iio_get_time_ns() - utility function to get a time stamp for events etc
> + * @indio_dev: device
> + */
> +s64 iio_get_time_ns(const struct iio_dev* indio_dev)
> +{
> + struct timespec tp;
> +
> + switch (indio_dev->clock_id) {
> + case CLOCK_REALTIME:
> + ktime_get_real_ts(&tp);
> + break;
> + case CLOCK_MONOTONIC:
> + ktime_get_ts(&tp);
> + break;
> + case CLOCK_MONOTONIC_RAW:
> + getrawmonotonic(&tp);
> + break;
> + case CLOCK_REALTIME_COARSE:
> + tp = current_kernel_time();
> + break;
> + case CLOCK_MONOTONIC_COARSE:
> + tp = get_monotonic_coarse();
> + break;
> + case CLOCK_BOOTTIME:
> + get_monotonic_boottime(&tp);
> + break;
> + case CLOCK_TAI:
> + timekeeping_clocktai(&tp);
> + break;
> + default:
> + BUG();
> + }
> +
> + return timespec_to_ns(&tp);
> +}
> +EXPORT_SYMBOL(iio_get_time_ns);
> +
> static int __init iio_init(void)
> {
> int ret;
> @@ -904,11 +942,61 @@ static ssize_t iio_show_dev_name(struct device *dev,
>
> static DEVICE_ATTR(name, S_IRUGO, iio_show_dev_name, NULL);
>
> +static ssize_t iio_show_clockid(struct device *dev,
> + struct device_attribute *attr, char *buf)
> +{
> + const struct iio_dev *indio_dev = dev_to_iio_dev(dev);
> + return sprintf(buf, "%d\n", indio_dev->clock_id);
I was rather expecting this to be a write of the actual string. Looks like
an integer at the moment.
> +}
> +
> +static ssize_t iio_store_clockid(struct device *dev,
> + struct device_attribute *attr,
> + const char *buf, size_t len)
> +{
> + int ret;
> + int clk;
> + struct iio_dev *indio_dev = dev_to_iio_dev(dev);
> + const struct iio_event_interface *ev_int = indio_dev->event_interface;
> +
> + ret = kstrtoint(buf, 0, &clk);
> + if (ret < 0)
> + return ret;
> +
> + switch (clk) {
> + case CLOCK_REALTIME:
> + case CLOCK_MONOTONIC:
> + case CLOCK_MONOTONIC_RAW:
> + case CLOCK_REALTIME_COARSE:
> + case CLOCK_MONOTONIC_COARSE:
> + case CLOCK_BOOTTIME:
> + case CLOCK_TAI:
> + break;
> + default:
> + return -EINVAL;
> + }
> +
> + ret = mutex_lock_interruptible(&indio_dev->mlock);
> + if (ret)
> + return ret;
> + if ((ev_int && iio_event_enabled(ev_int)) ||
> + iio_buffer_enabled(indio_dev)) {
> + mutex_unlock(&indio_dev->mlock);
> + return -EBUSY;
> + }
> + indio_dev->clock_id = clk;
> + mutex_unlock(&indio_dev->mlock);
> +
> + return len;
> +}
> +
> +static DEVICE_ATTR(clockid, S_IRUGO | S_IWUSR,
> + iio_show_clockid, iio_store_clockid);
> +
> static int iio_device_register_sysfs(struct iio_dev *indio_dev)
> {
> int i, ret = 0, attrcount, attrn, attrcount_orig = 0;
> struct iio_dev_attr *p;
> - struct attribute **attr;
> + struct attribute **attr, *clk = NULL;
>
> /* First count elements in any existing group */
> if (indio_dev->info->attrs) {
> @@ -923,16 +1011,25 @@ static int iio_device_register_sysfs(struct iio_dev *indio_dev)
> */
> if (indio_dev->channels)
> for (i = 0; i < indio_dev->num_channels; i++) {
> - ret = iio_device_add_channel_sysfs(indio_dev,
> - &indio_dev
> - ->channels[i]);
> + const struct iio_chan_spec *chan =
> + &indio_dev->channels[i];
> +
> + if (chan->type == IIO_TIMESTAMP)
> + clk = &dev_attr_clockid.attr;
> +
> + ret = iio_device_add_channel_sysfs(indio_dev, chan);
> if (ret < 0)
> goto error_clear_attrs;
> attrcount += ret;
> }
>
> + if (indio_dev->event_interface)
> + clk = &dev_attr_clockid.attr;
> +
> if (indio_dev->name)
> attrcount++;
> + if (clk)
> + attrcount++;
>
> indio_dev->chan_attr_group.attrs = kcalloc(attrcount + 1,
> sizeof(indio_dev->chan_attr_group.attrs[0]),
> @@ -953,6 +1050,8 @@ static int iio_device_register_sysfs(struct iio_dev *indio_dev)
> indio_dev->chan_attr_group.attrs[attrn++] = &p->dev_attr.attr;
> if (indio_dev->name)
> indio_dev->chan_attr_group.attrs[attrn++] = &dev_attr_name.attr;
> + if (clk)
> + indio_dev->chan_attr_group.attrs[attrn++] = clk;
>
> indio_dev->groups[indio_dev->groupcounter++] =
> &indio_dev->chan_attr_group;
> diff --git a/drivers/iio/industrialio-event.c b/drivers/iio/industrialio-event.c
> index cae332b..9480404 100644
> --- a/drivers/iio/industrialio-event.c
> +++ b/drivers/iio/industrialio-event.c
> @@ -44,6 +44,11 @@ struct iio_event_interface {
> struct mutex read_lock;
> };
>
> +bool iio_event_enabled(const struct iio_event_interface* ev_int)
> +{
> + return !! test_bit(IIO_BUSY_BIT_POS, &ev_int->flags);
!!test_bit
(i.e. no spacing preferred).
> +}
> +
> /**
> * iio_push_event() - try to add event to the list for userspace reading
> * @indio_dev: IIO device structure
> @@ -60,7 +65,7 @@ int iio_push_event(struct iio_dev *indio_dev, u64 ev_code, s64 timestamp)
> int copied;
>
> /* Does anyone care? */
> - if (test_bit(IIO_BUSY_BIT_POS, &ev_int->flags)) {
> + if (iio_event_enabled(ev_int)) {
>
> ev.id = ev_code;
> ev.timestamp = timestamp;
> @@ -180,8 +185,14 @@ int iio_event_getfd(struct iio_dev *indio_dev)
> if (ev_int == NULL)
> return -ENODEV;
>
> - if (test_and_set_bit(IIO_BUSY_BIT_POS, &ev_int->flags))
> - return -EBUSY;
> + fd = mutex_lock_interruptible(&indio_dev->mlock);
> + if (fd)
> + return fd;
> +
> + if (test_and_set_bit(IIO_BUSY_BIT_POS, &ev_int->flags)) {
> + fd = -EBUSY;
> + goto unlock;
> + }
>
> iio_device_get(indio_dev);
>
> @@ -194,6 +205,8 @@ int iio_event_getfd(struct iio_dev *indio_dev)
> kfifo_reset_out(&ev_int->det_events);
> }
>
> +unlock:
> + mutex_unlock(&indio_dev->mlock);
> return fd;
> }
>
> diff --git a/drivers/iio/industrialio-trigger.c b/drivers/iio/industrialio-trigger.c
> index ae2806a..cf93717 100644
> --- a/drivers/iio/industrialio-trigger.c
> +++ b/drivers/iio/industrialio-trigger.c
> @@ -251,7 +251,7 @@ static int iio_trigger_detach_poll_func(struct iio_trigger *trig,
> irqreturn_t iio_pollfunc_store_time(int irq, void *p)
> {
> struct iio_poll_func *pf = p;
> - pf->timestamp = iio_get_time_ns();
> + pf->timestamp = iio_get_time_ns(pf->indio_dev);
> return IRQ_WAKE_THREAD;
> }
> EXPORT_SYMBOL(iio_pollfunc_store_time);
> diff --git a/include/linux/iio/iio.h b/include/linux/iio/iio.h
> index ce9e9c1..904a5b0 100644
> --- a/include/linux/iio/iio.h
> +++ b/include/linux/iio/iio.h
> @@ -281,13 +281,7 @@ static inline bool iio_channel_has_info(const struct iio_chan_spec *chan,
> }, \
> }
>
> -/**
> - * iio_get_time_ns() - utility function to get a time stamp for events etc
> - **/
> -static inline s64 iio_get_time_ns(void)
> -{
> - return ktime_get_real_ns();
> -}
> +extern s64 iio_get_time_ns(const struct iio_dev*);
>
> /* Device operating modes */
> #define INDIO_DIRECT_MODE 0x01
> @@ -466,6 +460,7 @@ struct iio_buffer_setup_ops {
> * @chan_attr_group: [INTERN] group for all attrs in base directory
> * @name: [DRIVER] name of the device.
> * @info: [DRIVER] callbacks and constant info from driver
> + * @clock_id: [INTERN] timestamping clock posix identifier
> * @info_exist_lock: [INTERN] lock to prevent use during removal
> * @setup_ops: [DRIVER] callbacks to call before and after buffer
> * enable/disable
> @@ -506,6 +501,7 @@ struct iio_dev {
> struct attribute_group chan_attr_group;
> const char *name;
> const struct iio_info *info;
> + clockid_t clock_id;
> struct mutex info_exist_lock;
> const struct iio_buffer_setup_ops *setup_ops;
> struct cdev chrdev;
>
next prev parent reply other threads:[~2016-02-13 14:14 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-02-11 10:04 [RFC PATCH v1 0/3] iio: introduce timestamping clock selection Gregor Boirie
2016-02-11 10:04 ` [RFC PATCH v1 1/3] iio:core: timestamping clock selection support Gregor Boirie
2016-02-13 14:14 ` Jonathan Cameron [this message]
2016-02-14 17:43 ` Lars-Peter Clausen
2016-02-15 9:42 ` Gregor Boirie
2016-02-17 19:38 ` Jonathan Cameron
2016-02-18 9:25 ` Gregor Boirie
2016-02-11 10:04 ` [RFC PATCH v1 2/3] iio:core: timestamping clock resolution support Gregor Boirie
2016-02-11 10:04 ` [RFC PATCH v1 3/3] iio: make drivers use new timestamping clock API Gregor Boirie
2016-02-13 14:19 ` Jonathan Cameron
2016-02-15 9:11 ` Gregor Boirie
2016-02-13 14:12 ` [RFC PATCH v1 0/3] iio: introduce timestamping clock selection Jonathan Cameron
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=56BF3A49.1000908@kernel.org \
--to=jic23@kernel.org \
--cc=gregor.boirie@parrot.com \
--cc=lars@metafoo.de \
--cc=linux-iio@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).