Thread (9 messages) 9 messages, 3 authors, 2015-03-19

Re: [PATCH v5 4/4] mdio-mux-gpio: use new gpiod_get_array and gpiod_put_array functions

From: Rojhalat Ibrahim <hidden>
Date: 2015-03-04 14:34:01
Also in: linux-gpio

On Wednesday 04 March 2015 22:22:24 Alexandre Courbot wrote:
On Tue, Mar 3, 2015 at 6:45 PM, Rojhalat Ibrahim [off-list ref] wrote:
quoted
On Thursday 26 February 2015 18:54:53 Alexandre Courbot wrote:
quoted
quoted
One suggestion for a possible further improvement: it would be great
if the gpiod_set/get_array() functions would work on a struct
gpio_descs so users don't have to pass both the number of GPIOs and
the array.

I don't know whether it would be desirable to keep alternative
functions that preserve the current form, for users who want to set
multiple GPIOs but cannot use gpiod_get_array(). struct gpiod_descs is
easy to build, so maybe we don't need them?
I thought about that, but didn't want to change the interface in this
patch series.

Furthermore there is this use case (my use case):

I acquire a descriptor array for multiple data outputs and (among others) a
single descriptor for a clock output. Afterwards I want to set the data bits
and simultaneously clear the clock bit (using gpiod_set_array) before setting
only the clock output (using gpiod_set_value).

Therefore I need an array containing the data bits and the clock bit which
is easy to build.

I could also create a struct gpiod_descs but it would be more complicated
since I would have to allocate a new struct before populating it with the
descriptors and also free the allocated memory afterwards. It's not really
a big deal but more complicated than before.

But this might not be a very common use case.

If we can assume that for the common use case the group of descriptors that
can be acquired using gpiod_get_array() is the same group that should be
set using gpiod_set_array(), it might make sense to change the interface.
Ah, thanks for sharing your use-case. I wish I had heard it earlier as
it seems we should make things more flexible than they currently are.

If I followed you correctly, you need to call gpiod_get_array() to
obtain the data lines, and gpiod_get() for the clock line. Then you
need to allocate a new array of gpio_desc * and copy all the
descriptors there before calling gpiod_set_array(). So simply put, the
struct gpio_descs you obtained is just useless to you.

It seems like we have been doing things wrong. Maybe gpiod_get_array()
should simply take a pointer to a gpio_desc * array that it would
fill, as you originally proposed?

So now, the question is: do we need struct gpiod_descs at all? It can
help reducing the number of arguments passed to functions, but also
makes the whole API more rigid. Use it with gpiod_get_array(), and you
end up with unneeded copies and memory allocations. Pass it to
gpiod_set_array() and you cannot do things like setting only part of
the GPIOs you requested.

Argh, and looking closer there is some possible confusion between
gpiod_set_array() and gpiod_get_array(). One might expect the latter
to return the *values* of the GPIOs, considering the name of the
former, while it actually is the array counterpart of gpiod_get(). To
be consistent with the single descriptor API, I suppose we should
rename gpiod_set_array() to gpiod_set_array_value(). But that's a
separate issue.

For now, since you are the main user of the array API, what is your
opinion about gpiod_descs? Do you think it is worth making the API
less flexible just to not have to carry an array lengh separately?
Should we just get rid of it?
I don't think it's that bad.

As I said before my use case might be very different from the common use case.

Furthermore the alternative API, that fills a pre-allocated array, wouldn't
make things easier. I would still have an array of data lines and a separate
descriptor for the clock. For setting them all together I would still have to
create an array containing the data and the clock descriptors. Creating this
array is not a big deal because it can be a static global array or an on stack
array in the context of a function. So no calls to kalloc / kfree are needed.

And the interface as proposed in this series is very convenient for obtaining
all the GPIOs belonging to a group with a single function call and without
having to know the number of GPIOs within the group beforehand.

So if we want to support different use cases, I think it's quite good as it is.
People who want to set a group of GPIOs as obtained by gpiod_get_array() can
do so with a single call to gpiod_set_array(), the only overhead being that
they have to specify the two elements of struct gpiod_descs explicitly.
Likewise people who want to set a group of GPIOs obtained with a combination
of calls to gpiod_get_array() and gpiod_get() can do so too. They just have
to create that group first.

On the other hand if gpiod_set_array() would require a struct gpiod_descs as
argument the creation of a group for the second use case would become more
complicated as you would have to allocate a struct instead of an array, etc.

So let's just keep it the way it is and get this series merged.

About the confusing function names: I would be happy to submit a patch
renaming gpiod_set_array() to gpiod_set_array_value(), once this has been
merged. I'm a little concerned about the length of some function names though.
Isn't gpiod_set_raw_array_value_cansleep() a bit long?

Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help