From: Jonathan Cameron <jic23@kernel.org>
To: William Breathitt Gray <vilhelm.gray@gmail.com>
Cc: knaack.h@gmx.de, lars@metafoo.de, pmeerw@pmeerw.net,
benjamin.gaignard@linaro.org, linux-kernel@vger.kernel.org,
linux-iio@vger.kernel.org
Subject: Re: [PATCH 2/3] iio: Introduce the generic counter interface
Date: Sun, 3 Sep 2017 18:37:11 +0100 [thread overview]
Message-ID: <20170903183711.5cffb9bd@archlinux> (raw)
In-Reply-To: <20170828155707.GB16755@sophia>
On Mon, 28 Aug 2017 11:57:07 -0400
William Breathitt Gray <vilhelm.gray@gmail.com> wrote:
> On Sun, Aug 20, 2017 at 12:40:02PM +0100, Jonathan Cameron wrote:
> >On Mon, 31 Jul 2017 12:03:23 -0400
> >William Breathitt Gray <vilhelm.gray@gmail.com> wrote:
> >
> >> This patch introduces the IIO generic counter interface for supporting
> >> counter devices. The generic counter interface serves as a catch-all to
> >> enable rudimentary support for devices that qualify as counters. More
> >> specific and apt counter interfaces may be developed on top of the
> >> generic counter interface, and those interfaces should be used by
> >> drivers when possible rather than the generic counter interface.
> >>
> >> In the context of the IIO generic counter interface, a counter is
> >> defined as a device that reports one or more "counter values" based on
> >> the state changes of one or more "counter signals" as evaluated by a
> >> defined "counter function."
> >>
> >> The IIO generic counter interface piggybacks off of the IIO core. This
> >> is primarily used to leverage the existing sysfs setup: the IIO_COUNT
> >> channel attributes represent the "counter value," while the IIO_SIGNAL
> >> channel attributes represent the "counter signal;" auxilary IIO_COUNT
> >> attributes represent the "counter signal" connections and their
> >> respective state change configurations which trigger an associated
> >> "counter function" evaluation.
> >>
> >> The iio_counter_ops structure serves as a container for driver callbacks
> >> to communicate with the device; function callbacks are provided to read
> >> and write various "counter signals" and "counter values," and set and
> >> get the "trigger mode" and "function mode" for various "counter signals"
> >> and "counter values" respectively.
> >>
> >> To support a counter device, a driver must first allocate the available
> >> "counter signals" via iio_counter_signal structures. These "counter
> >> signals" should be stored as an array and set to the init_signals member
> >> of an allocated iio_counter structure before the counter is registered.
> >>
> >> "Counter values" may be allocated via iio_counter_value structures, and
> >> respective "counter signal" associations made via iio_counter_trigger
> >> structures. Initial associated iio_counter_trigger structures may be
> >> stored as an array and set to the the init_triggers member of the
> >> respective iio_counter_value structure. These iio_counter_value
> >> structures may be set to the init_values member of an allocated
> >> iio_counter structure before the counter is registered if so desired.
> >>
> >> A counter device is registered to the system by passing the respective
> >> initialized iio_counter structure to the iio_counter_register function;
> >> similarly, the iio_counter_unregister function unregisters the
> >> respective counter.
> >>
> >> Signed-off-by: William Breathitt Gray <vilhelm.gray@gmail.com>
> >
> >Hi William,
> >
> >A few minor points inline as a starting point. I'm going to want to dig
> >into this in a lot more detail but don't have the time today (or possibly
> >for a few more weeks - sorry about that!)
>
> Thank you for the quick review. Looking over your review points and my
> code again, it's become rather apparent to me that my implementation is
> burdenly opaque with its lack of apt comments to document the rationale
> of certain sections of code. I'll repair to remedy that in version 2 of
> this patchset.
>
> By the way, feel free to take your time reviewing, I'm in no particular
> rush myself. In fact, with the anticipated proper documentation coming I
> expect version 2 to a bit easily to digest for you than this intial
> patchset. As well, in general I prefer to get this interface committed
> late but correct, rather than soon but immature.
All sounds good. There is a fair bit here, so not surprising that
it gets a bit complex :)
>
> I've provided my responses inline to your specific review points.
>
> Sincerely,
>
> William Breathitt Gray
<snip>
> >> +
> >> +static ssize_t __iio_counter_trigger_mode_write(struct iio_dev *indio_dev,
> >> + uintptr_t priv, const struct iio_chan_spec *chan, const char *buf,
> >> + size_t len)
> >> +{
> >> + struct iio_counter *const counter = iio_priv(indio_dev);
> >> + struct iio_counter_value *value;
> >> + ssize_t err;
> >> + struct iio_counter_trigger *trigger;
> >> + const int signal_id = *(int *)((void *)priv);
> >Given you don't go through the void * cast in _read I'm thinking it's not
> >needed here either.
>
> I'm aware that we typically do not follow the C99 standard in the Linux
> kernel code, but since the uintptr_t typedef is modeled after the C99
> uintptr_t, I considered it appropriate to follow C99 in this case: the
> C99 standard requires an explicit conversion to void * from intptr_t
> before converting to another pointer type for dereferencing.
Fair enough.
>
> Despite the standard requirement, I agree that it is awkward to see the
> explicit cast to void * (likely because uintptr_t is not intended to be
> dereferenced in the context of the standard), so I'll be willing to
> remove it in this case if you believe it'll make the code clearer to
> understand.
>
> Just out of curiousity: why was uintptr_t choosen for this parameter
> rather than void *?
I'd imagine it's about explicitly tracking userspace pointers rather than
kernel ones. They could probably have have a uvoidptr_t but for some
reason decided not to...
<snip>
> >> +
> >> +static int __iio_counter_write_raw(struct iio_dev *indio_dev,
> >> + struct iio_chan_spec const *chan, int val, int val2, long mask)
> >> +{
> >> + struct iio_counter *const counter = iio_priv(indio_dev);
> >> + struct iio_counter_signal *signal;
> >> + int retval;
> >> + struct iio_counter_value *value;
> >> +
> >> + if (mask != IIO_CHAN_INFO_RAW)
> >> + return -EINVAL;
> >> +
> >> + switch (chan->type) {
> >> + case IIO_SIGNAL:
> >> + if (!counter->ops->signal_write)
> >> + return -EINVAL;
> >> +
> >> + mutex_lock(&counter->signal_list_lock);
> >> + signal = __iio_counter_signal_find_by_id(counter,
> >> + chan->channel2);
> >> + if (!signal) {
> >> + mutex_unlock(&counter->signal_list_lock);
> >> + return -EINVAL;
> >> + }
> >> +
> >> + retval = counter->ops->signal_write(counter, signal, val, val2);
> >> + mutex_unlock(&counter->signal_list_lock);
> >> +
> >> + return retval;
> >> + case IIO_COUNT:
> >> + if (!counter->ops->value_write)
> >> + return -EINVAL;
> >> +
> >> + mutex_lock(&counter->value_list_lock);
> >> + value = __iio_counter_value_find_by_id(counter, chan->channel2);
> >> + if (!value) {
> >> + mutex_unlock(&counter->value_list_lock);
> >> + return -EINVAL;
> >> + }
> >> +
> >> + retval = counter->ops->value_write(counter, value, val, val2);
> >> + mutex_unlock(&counter->value_list_lock);
> >> +
> >> + return retval;
> >> + default:
> >
> >This case definitely needs a comment!
> >I think you overwrite any write_raw callbacks passed in and hence this
> >is a infinite recursion...
> >Could be wrong though ;)
>
> I apologize, this looks like one of those cases where I should have
> provided some better documentation about the architecture of generic
> counter interface implementation. I'll make sure to make this clearer in
> the version 2 documentation and comments.
>
> However, I'll try to explain what's going on. The generic counter
> interface sits a layer above the IIO core, so drivers which use the
> generic counter interface do not directly supply IIO core write_raw
> callbacks, but rather provide generic counter signal_write/value_write
> callbacks (a passed write_raw callback is possible for non-counter IIO
> channels).
>
> The generic counter interface hooks itself via __iio_counter_write_raw
> to the IIO core write_raw. The __iio_counter_write_raw function handles
> the mapping to ensure that signal_write gets called for a generic
> counter Signal, value_write gets called for a generic counter Value, and
> a passed write_raw gets called for a passed non-counter IIO channel.
>
> The reason for this __iio_counter_write_raw function is to provide an
> abstraction for the signal_write/value_write functions to have access to
> generic counter interface parameters not available via the regular
> write_raw parameters. In theory, a driver utilizing the generic counter
> interface for a counter device does not need to know that it's utilizing
> IIO core under the hood since to it can handle all its counter device
> needs via the signal_write/value_write callbacks.
Thanks for the explanation. I'd somehow missed that entirely.
<snip>
next prev parent reply other threads:[~2017-09-03 17:37 UTC|newest]
Thread overview: 15+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-07-31 16:02 [PATCH 0/3] iio: Introduce the generic counter interface William Breathitt Gray
2017-07-31 16:03 ` [PATCH 1/3] iio: Implement counter channel specification and IIO_SIGNAL constant William Breathitt Gray
2017-07-31 16:03 ` [PATCH 2/3] iio: Introduce the generic counter interface William Breathitt Gray
2017-07-31 23:15 ` kbuild test robot
2017-08-20 11:40 ` Jonathan Cameron
2017-08-28 15:57 ` William Breathitt Gray
2017-09-03 17:37 ` Jonathan Cameron [this message]
2017-07-31 16:03 ` [PATCH 3/3] iio: 104-quad-8: Add IIO generic counter interface support William Breathitt Gray
2017-08-20 12:11 ` Jonathan Cameron
2017-08-28 16:23 ` William Breathitt Gray
2017-09-03 17:50 ` Jonathan Cameron
2017-09-03 18:24 ` Jonathan Cameron
2017-08-20 12:00 ` [PATCH 0/3] iio: Introduce the generic counter interface Jonathan Cameron
2017-08-28 14:16 ` William Breathitt Gray
2017-09-03 17:44 ` 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=20170903183711.5cffb9bd@archlinux \
--to=jic23@kernel.org \
--cc=benjamin.gaignard@linaro.org \
--cc=knaack.h@gmx.de \
--cc=lars@metafoo.de \
--cc=linux-iio@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=pmeerw@pmeerw.net \
--cc=vilhelm.gray@gmail.com \
/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 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.