Re: [PATCH RESEND 1/5 v6] gpio: Add a block GPIO API to gpiolib

2012-11-02 Thread Roland Stigge
On 10/31/2012 07:59 PM, Grant Likely wrote:
>> Pin direction currently needs to be set up separately, analogous to
>> requesting gpios. Need to document this better, right. The assumption is
>> that I/O needs to be efficient primarily, before bloating the API with
>> direction functions. Or should I add functions for this?
> 
> Since this is a userspace facing ABI, once it is merged it cannot be
> changed in an incompatible way. I cannot merge it until there is at
> least a plan for how to handle all of the reasonable use cases. That
> means it must support set/clear or mask operations. Also, if it sticks
> with the design of grouping pins from multiple controllers, then it
> needs to handle explicitly constraining what order operations are
> performed in at the time of the operation. At the time of setup
> doesn't work since constraints between pins may not always be in the
> same order.
> 
> I really think you should consider implementing a command stream type
> of interface.

Yes, understand. What do you consider a good example of a command stream
type interface? Link or hint appreciated!

There was already mentioned the idea of a device node which can be
interfaced to via ioctl() for the various operations. Can it be a
"struct miscdevice" or do you require sth. more sophisticated?

Thanks in advance,

Roland
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH RESEND 1/5 v6] gpio: Add a block GPIO API to gpiolib

2012-11-02 Thread Roland Stigge
On 10/31/2012 07:59 PM, Grant Likely wrote:
 Pin direction currently needs to be set up separately, analogous to
 requesting gpios. Need to document this better, right. The assumption is
 that I/O needs to be efficient primarily, before bloating the API with
 direction functions. Or should I add functions for this?
 
 Since this is a userspace facing ABI, once it is merged it cannot be
 changed in an incompatible way. I cannot merge it until there is at
 least a plan for how to handle all of the reasonable use cases. That
 means it must support set/clear or mask operations. Also, if it sticks
 with the design of grouping pins from multiple controllers, then it
 needs to handle explicitly constraining what order operations are
 performed in at the time of the operation. At the time of setup
 doesn't work since constraints between pins may not always be in the
 same order.
 
 I really think you should consider implementing a command stream type
 of interface.

Yes, understand. What do you consider a good example of a command stream
type interface? Link or hint appreciated!

There was already mentioned the idea of a device node which can be
interfaced to via ioctl() for the various operations. Can it be a
struct miscdevice or do you require sth. more sophisticated?

Thanks in advance,

Roland
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH RESEND 1/5 v6] gpio: Add a block GPIO API to gpiolib

2012-11-01 Thread Grant Likely
On Wed, Oct 31, 2012 at 8:30 PM, Mark Brown
 wrote:
> On Wed, Oct 31, 2012 at 04:00:17PM +0100, Grant Likely wrote:
>
>> For the API, I don't think it is a good idea at all to try and
>> abstract away gpios on multiple controllers. I understand that it
>> makes life a lot easier for userspace to abstract those details away,
>> but the problem is that it hides very important information about how
>> the system is actually constructed that is important to actually get
>> things to work. For example, say you have a gpio-connected device with
>> the constraint that GPIOA must change either before or at the same
>> time as GPIOB, but never after. If those GPIOs are on separate
>> controllers, then the order is completely undefined, and the user has
>> no way to control that other than to fall back to manipulating GPIOs
>> one at a time again (and losing all the performance benefits). Either
>> controller affinity needs to be explicit in the API, or the API needs
>> to be constraint oriented (ie. a stream of commands and individual
>> commands can be coalesced if they meet the constraints**). Also, the
>> API requires remapping the GPIO numbers which forces the code to be a
>> lot more complex than it needs to be.
>
> It feels like I'm missing something here but can we not simply say that
> if the user cares about the ordering of the signal changes within an
> update then they should be doing two separate updates?  Most of the
> cases I'm aware of do things as an update with a strobe or clock that
> latches the values.
>
> The big advantage of grouping things together is that it means that we
> centralise the fallback code.

The internal ABI is less of an issue because it is a whole lot easier
to change compared to a userspace ABI (though I think we can do a lot
better before deciding to merge it). Userspace also appears to be the
intended usage, so I've focused my review on that use case.

g.
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH RESEND 1/5 v6] gpio: Add a block GPIO API to gpiolib

2012-11-01 Thread Jean-Christophe PLAGNIOL-VILLARD
On 19:59 Wed 31 Oct , Grant Likely wrote:
> Hi Roland
> 
> On Wed, Oct 31, 2012 at 6:19 PM, Roland Stigge  wrote:
> > On 10/31/2012 04:00 PM, Grant Likely wrote:
> >> For the API, I don't think it is a good idea at all to try and
> >> abstract away gpios on multiple controllers. I understand that it
> >> makes life a lot easier for userspace to abstract those details away,
> >> but the problem is that it hides very important information about how
> >> the system is actually constructed that is important to actually get
> >> things to work. For example, say you have a gpio-connected device with
> >> the constraint that GPIOA must change either before or at the same
> >> time as GPIOB, but never after. If those GPIOs are on separate
> >> controllers, then the order is completely undefined
> >
> > It is correct that it's not (yet) well documented and the API is also
> > not very explicit about it, but the actual approach of the manipulation
> > order is to let drivers handle gpios "as simultaneous as possible" and
> > when not possible, do it in the _order of bits specified_ (either
> > defined at the device tree level, or when created via
> > block_gpio_create() directly).
> 
> The documentation is actually fine. I do understand that the intent is
> "as simultaneous as possible", but I accept the point that the order
> of specification affects the behaviour*. However, it still remains
> that the method used by the ABI abstracts at the wrong level and that
> blocking arbitrary GPIO pins into a single virtual GPIO register is a
> bad idea.
> 
> *note that the current code doesn't implement that intended behaviour
> either since the gpios are processed in the order of the controllers,
> not the order of the bits.
> 
> > I'm not sure how far you tested the API in depth: You can already define
> > a block that maps onto a subset of gpios on a controller and internally
> > of course maps onto those set and clear operations. Whenever you need to
> > manipulate a different subset (whether disjoint or overlapping), you can
> > easily define _additional_ blocks. From my experience, this solves most
> > of the real world problems when n-bit busses are bit banged over GPIOs.
> > Doesn't this already solve this (in a different way, though)?
> 
> Blech! Requiring a new block for each possible combination of
> write-at-once bits is a horrible ABI. That just strengthens my opinion
> that the abstraction isn't right yet.
> 
> > Pin direction currently needs to be set up separately, analogous to
> > requesting gpios. Need to document this better, right. The assumption is
> > that I/O needs to be efficient primarily, before bloating the API with
> > direction functions. Or should I add functions for this?
> 
> Since this is a userspace facing ABI, once it is merged it cannot be
> changed in an incompatible way. I cannot merge it until there is at
> least a plan for how to handle all of the reasonable use cases. That
> means it must support set/clear or mask operations. Also, if it sticks
> with the design of grouping pins from multiple controllers, then it
> needs to handle explicitly constraining what order operations are
> performed in at the time of the operation. At the time of setup
> doesn't work since constraints between pins may not always be in the
> same order.
> 
> I really think you should consider implementing a command stream type
> of interface.
I agreed with Grant and I'm not also a fan of the sysfs ABI

as I already point out in the previous version and Linus too

Best Regards,
J.
> 
> g.
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH RESEND 1/5 v6] gpio: Add a block GPIO API to gpiolib

2012-11-01 Thread Jean-Christophe PLAGNIOL-VILLARD
On 19:59 Wed 31 Oct , Grant Likely wrote:
 Hi Roland
 
 On Wed, Oct 31, 2012 at 6:19 PM, Roland Stigge sti...@antcom.de wrote:
  On 10/31/2012 04:00 PM, Grant Likely wrote:
  For the API, I don't think it is a good idea at all to try and
  abstract away gpios on multiple controllers. I understand that it
  makes life a lot easier for userspace to abstract those details away,
  but the problem is that it hides very important information about how
  the system is actually constructed that is important to actually get
  things to work. For example, say you have a gpio-connected device with
  the constraint that GPIOA must change either before or at the same
  time as GPIOB, but never after. If those GPIOs are on separate
  controllers, then the order is completely undefined
 
  It is correct that it's not (yet) well documented and the API is also
  not very explicit about it, but the actual approach of the manipulation
  order is to let drivers handle gpios as simultaneous as possible and
  when not possible, do it in the _order of bits specified_ (either
  defined at the device tree level, or when created via
  block_gpio_create() directly).
 
 The documentation is actually fine. I do understand that the intent is
 as simultaneous as possible, but I accept the point that the order
 of specification affects the behaviour*. However, it still remains
 that the method used by the ABI abstracts at the wrong level and that
 blocking arbitrary GPIO pins into a single virtual GPIO register is a
 bad idea.
 
 *note that the current code doesn't implement that intended behaviour
 either since the gpios are processed in the order of the controllers,
 not the order of the bits.
 
  I'm not sure how far you tested the API in depth: You can already define
  a block that maps onto a subset of gpios on a controller and internally
  of course maps onto those set and clear operations. Whenever you need to
  manipulate a different subset (whether disjoint or overlapping), you can
  easily define _additional_ blocks. From my experience, this solves most
  of the real world problems when n-bit busses are bit banged over GPIOs.
  Doesn't this already solve this (in a different way, though)?
 
 Blech! Requiring a new block for each possible combination of
 write-at-once bits is a horrible ABI. That just strengthens my opinion
 that the abstraction isn't right yet.
 
  Pin direction currently needs to be set up separately, analogous to
  requesting gpios. Need to document this better, right. The assumption is
  that I/O needs to be efficient primarily, before bloating the API with
  direction functions. Or should I add functions for this?
 
 Since this is a userspace facing ABI, once it is merged it cannot be
 changed in an incompatible way. I cannot merge it until there is at
 least a plan for how to handle all of the reasonable use cases. That
 means it must support set/clear or mask operations. Also, if it sticks
 with the design of grouping pins from multiple controllers, then it
 needs to handle explicitly constraining what order operations are
 performed in at the time of the operation. At the time of setup
 doesn't work since constraints between pins may not always be in the
 same order.
 
 I really think you should consider implementing a command stream type
 of interface.
I agreed with Grant and I'm not also a fan of the sysfs ABI

as I already point out in the previous version and Linus too

Best Regards,
J.
 
 g.
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH RESEND 1/5 v6] gpio: Add a block GPIO API to gpiolib

2012-11-01 Thread Grant Likely
On Wed, Oct 31, 2012 at 8:30 PM, Mark Brown
broo...@opensource.wolfsonmicro.com wrote:
 On Wed, Oct 31, 2012 at 04:00:17PM +0100, Grant Likely wrote:

 For the API, I don't think it is a good idea at all to try and
 abstract away gpios on multiple controllers. I understand that it
 makes life a lot easier for userspace to abstract those details away,
 but the problem is that it hides very important information about how
 the system is actually constructed that is important to actually get
 things to work. For example, say you have a gpio-connected device with
 the constraint that GPIOA must change either before or at the same
 time as GPIOB, but never after. If those GPIOs are on separate
 controllers, then the order is completely undefined, and the user has
 no way to control that other than to fall back to manipulating GPIOs
 one at a time again (and losing all the performance benefits). Either
 controller affinity needs to be explicit in the API, or the API needs
 to be constraint oriented (ie. a stream of commands and individual
 commands can be coalesced if they meet the constraints**). Also, the
 API requires remapping the GPIO numbers which forces the code to be a
 lot more complex than it needs to be.

 It feels like I'm missing something here but can we not simply say that
 if the user cares about the ordering of the signal changes within an
 update then they should be doing two separate updates?  Most of the
 cases I'm aware of do things as an update with a strobe or clock that
 latches the values.

 The big advantage of grouping things together is that it means that we
 centralise the fallback code.

The internal ABI is less of an issue because it is a whole lot easier
to change compared to a userspace ABI (though I think we can do a lot
better before deciding to merge it). Userspace also appears to be the
intended usage, so I've focused my review on that use case.

g.
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH RESEND 1/5 v6] gpio: Add a block GPIO API to gpiolib

2012-10-31 Thread Mark Brown
On Wed, Oct 31, 2012 at 04:00:17PM +0100, Grant Likely wrote:

> For the API, I don't think it is a good idea at all to try and
> abstract away gpios on multiple controllers. I understand that it
> makes life a lot easier for userspace to abstract those details away,
> but the problem is that it hides very important information about how
> the system is actually constructed that is important to actually get
> things to work. For example, say you have a gpio-connected device with
> the constraint that GPIOA must change either before or at the same
> time as GPIOB, but never after. If those GPIOs are on separate
> controllers, then the order is completely undefined, and the user has
> no way to control that other than to fall back to manipulating GPIOs
> one at a time again (and losing all the performance benefits). Either
> controller affinity needs to be explicit in the API, or the API needs
> to be constraint oriented (ie. a stream of commands and individual
> commands can be coalesced if they meet the constraints**). Also, the
> API requires remapping the GPIO numbers which forces the code to be a
> lot more complex than it needs to be.

It feels like I'm missing something here but can we not simply say that
if the user cares about the ordering of the signal changes within an
update then they should be doing two separate updates?  Most of the
cases I'm aware of do things as an update with a strobe or clock that
latches the values.

The big advantage of grouping things together is that it means that we
centralise the fallback code.

> I would rather see new attribute(s) added to the gpiochip's directory
> to allow modifying all the pins on a given controller. It's
> considerably less complex, and I'm a lot happier about extending the
> sysfs ABI in that way than committing to the remapping block approach.

When I've looked at this stuff I've only looked at and thought about in
kernel users.  The gpiolib sysfs ABI is already fun enough :)
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH RESEND 1/5 v6] gpio: Add a block GPIO API to gpiolib

2012-10-31 Thread Grant Likely
Hi Roland

On Wed, Oct 31, 2012 at 6:19 PM, Roland Stigge  wrote:
> On 10/31/2012 04:00 PM, Grant Likely wrote:
>> For the API, I don't think it is a good idea at all to try and
>> abstract away gpios on multiple controllers. I understand that it
>> makes life a lot easier for userspace to abstract those details away,
>> but the problem is that it hides very important information about how
>> the system is actually constructed that is important to actually get
>> things to work. For example, say you have a gpio-connected device with
>> the constraint that GPIOA must change either before or at the same
>> time as GPIOB, but never after. If those GPIOs are on separate
>> controllers, then the order is completely undefined
>
> It is correct that it's not (yet) well documented and the API is also
> not very explicit about it, but the actual approach of the manipulation
> order is to let drivers handle gpios "as simultaneous as possible" and
> when not possible, do it in the _order of bits specified_ (either
> defined at the device tree level, or when created via
> block_gpio_create() directly).

The documentation is actually fine. I do understand that the intent is
"as simultaneous as possible", but I accept the point that the order
of specification affects the behaviour*. However, it still remains
that the method used by the ABI abstracts at the wrong level and that
blocking arbitrary GPIO pins into a single virtual GPIO register is a
bad idea.

*note that the current code doesn't implement that intended behaviour
either since the gpios are processed in the order of the controllers,
not the order of the bits.

> I'm not sure how far you tested the API in depth: You can already define
> a block that maps onto a subset of gpios on a controller and internally
> of course maps onto those set and clear operations. Whenever you need to
> manipulate a different subset (whether disjoint or overlapping), you can
> easily define _additional_ blocks. From my experience, this solves most
> of the real world problems when n-bit busses are bit banged over GPIOs.
> Doesn't this already solve this (in a different way, though)?

Blech! Requiring a new block for each possible combination of
write-at-once bits is a horrible ABI. That just strengthens my opinion
that the abstraction isn't right yet.

> Pin direction currently needs to be set up separately, analogous to
> requesting gpios. Need to document this better, right. The assumption is
> that I/O needs to be efficient primarily, before bloating the API with
> direction functions. Or should I add functions for this?

Since this is a userspace facing ABI, once it is merged it cannot be
changed in an incompatible way. I cannot merge it until there is at
least a plan for how to handle all of the reasonable use cases. That
means it must support set/clear or mask operations. Also, if it sticks
with the design of grouping pins from multiple controllers, then it
needs to handle explicitly constraining what order operations are
performed in at the time of the operation. At the time of setup
doesn't work since constraints between pins may not always be in the
same order.

I really think you should consider implementing a command stream type
of interface.

g.
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH RESEND 1/5 v6] gpio: Add a block GPIO API to gpiolib

2012-10-31 Thread Roland Stigge
Hi Linus,

thanks for your notes, comments below:

On 10/31/2012 03:06 PM, Linus Walleij wrote:
>> +struct gpio_block *gpio_block_create(unsigned *gpios, size_t size,
>> +const char *name)
>> +{
>> +   struct gpio_block *block;
>> +   struct gpio_block_chip *gbc;
>> +   struct gpio_remap *remap;
>> +   void *tmp;
>> +   int i;
>> +
>> +   if (size < 1 || size > sizeof(unsigned long) * 8)
>> +   return ERR_PTR(-EINVAL);
> 
> If the most GPIOs in a block is BITS_PER_LONG, why is the
> latter clause not size > BITS_PER_LONG?

Good catch, thanks! :-)

>> +   for (i = 0; i < size; i++)
>> +   if (!gpio_is_valid(gpios[i]))
>> +   return ERR_PTR(-EINVAL);
>> +
>> +   block = kzalloc(sizeof(struct gpio_block), GFP_KERNEL);
>> +   if (!block)
>> +   return ERR_PTR(-ENOMEM);
> 
> If these were instead glued to a struct device you could do
> devm_kzalloc() here and have it garbage collected.

Good, will do.

> This is why
> https://blueprints.launchpad.net/linux-linaro/+spec/gpiochip-to-dev
> needs to happen. (Sorry for hyperlinking.)
> 
>> +   block->name = name;
>> +   block->ngpio = size;
>> +   block->gpio = kzalloc(sizeof(*block->gpio) * size, GFP_KERNEL);
>> +   if (!block->gpio)
>> +   goto err1;
>> +
>> +   memcpy(block->gpio, gpios, sizeof(*block->gpio) * size);
>> +
>> +   for (i = 0; i < size; i++) {
>> +   struct gpio_chip *gc = gpio_to_chip(gpios[i]);
>> +   int bit = gpios[i] - gc->base;
>> +   int index = gpio_block_chip_index(block, gc);
>> +
>> +   if (index < 0) {
>> +   block->nchip++;
>> +   tmp = krealloc(block->gbc,
>> +  sizeof(struct gpio_block_chip) *
>> +  block->nchip, GFP_KERNEL);
> 
> Don't do this dynamic array business. Use a linked list instead.

OK, I checked the important spots where access to the two lists (gbc and
remap) happen (set and get functions), and the access is always
sequential, monotonic. So will use lists. Thanks.

> [...]
> /*
>  * Maybe I'm a bit picky on comment style but I prefer
>  * that the first line of a multi-line comment is blank.
>  * Applies everywhere.
>  */

As noted earlier in the discussion, current gpiolib.c's convention is
done first-line-not-blank. So I sticked to this (un)convention. But can
change this - you are not the first one pointing this out. :-)

>> +   if (!tmp) {
>> +   kfree(gbc->remap);
>> +   goto err3;
>> +   }
>> +   gbc->remap = tmp;
>> +   remap = >remap[gbc->nremap - 1];
>> +   remap->offset = bit - i;
>> +   remap->mask = 0;
>> +   }
>> +
>> +   /* represents the mask necessary for bit reordering between
>> +* gpio_block (i.e. as specified on gpio_block_get() and
>> +* gpio_block_set()) and gpio_chip domain (i.e. as specified 
>> on
>> +* the driver's .set_block() and .get_block())
>> +*/
>> +   remap->mask |= BIT(i);
>> +   }
>> +
>> +   return block;
>> +err3:
>> +   for (i = 0; i < block->nchip - 1; i++)
>> +   kfree(block->gbc[i].remap);
>> +   kfree(block->gbc);
>> +err2:
>> +   kfree(block->gpio);
>> +err1:
>> +   kfree(block);
>> +   return ERR_PTR(-ENOMEM);
>> +}
>> +EXPORT_SYMBOL_GPL(gpio_block_create);
>> +
>> +void gpio_block_free(struct gpio_block *block)
>> +{
>> +   int i;
>> +
>> +   for (i = 0; i < block->nchip; i++)
>> +   kfree(block->gbc[i].remap);
>> +   kfree(block->gpio);
>> +   kfree(block->gbc);
>> +   kfree(block);
>> +}
>> +EXPORT_SYMBOL_GPL(gpio_block_free);
> 
> So if we only had a real struct device  inside the gpiochip all
> this boilerplate would go away, as devm_* take care of releasing
> the resources.

Right. I guess you mean struct gpio_block here which should have a dev?
(Having gpiochip as a dev also would be best, though.) :-)

We need a separate dev for struct gpio_block, since those can be defined
dynamically (i.e. often) during the lifespan of gpio and gpiochip, so
garbage collection would be deferred for too long.

Thanks,

Roland
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH RESEND 1/5 v6] gpio: Add a block GPIO API to gpiolib

2012-10-31 Thread Roland Stigge
Hi Grant,

thank you for your feedback!

Notes below.

On 10/31/2012 04:00 PM, Grant Likely wrote:
> Linus and I just sat down and talked about your changes. I think I
> understand what you need to do, but I've got concerns about the
> approach. I'm already not a big fan of the sysfs gpio interface
> design*, so you can understand that I'm not keen to extend the
> interface further. At the very least, I want to be really careful
> about the form that the extension takes.
> 
> First off, thank you for writing good documentation. That makes it a
> lot easier to understand how the series is intended to be used, and I
> really appreciate it.
> 
> For the API, I don't think it is a good idea at all to try and
> abstract away gpios on multiple controllers. I understand that it
> makes life a lot easier for userspace to abstract those details away,
> but the problem is that it hides very important information about how
> the system is actually constructed that is important to actually get
> things to work. For example, say you have a gpio-connected device with
> the constraint that GPIOA must change either before or at the same
> time as GPIOB, but never after. If those GPIOs are on separate
> controllers, then the order is completely undefined

It is correct that it's not (yet) well documented and the API is also
not very explicit about it, but the actual approach of the manipulation
order is to let drivers handle gpios "as simultaneous as possible" and
when not possible, do it in the _order of bits specified_ (either
defined at the device tree level, or when created via
block_gpio_create() directly).

I consider it a good thing to abstract things away if possible here, if
it is well documented what actually happens, which info should be
available from the definition and the possibilities of the drivers and
hardware actually used (the optional block gpio interface must be well
implemented in the respective driver, and when combining multiple gpio
controller chips, it should be clear that certain realtime timings on a
resulting virtual n-bit bus are not possible.)

> Second, the API appears a little naive in the way it approaches
> changing values. It makes the assumption that every gpio in the block
> will be written at the same time, which doesn't take into account that
> even within a block it is highly likely that only a subset of the
> gpios need to be manipulated. A lot of GPIO controllers implement
> separate 'set' and 'clear' registers for exactly this reason. The API
> needs to allow users to choose a subset for manipulation. The ABI
> needs to either have separate 'set' and 'clear' operations, or
> operations need to have both mask and value arguments. Similarly, how
> do users manipulate pin direction with this ABI?

I'm not sure how far you tested the API in depth: You can already define
a block that maps onto a subset of gpios on a controller and internally
of course maps onto those set and clear operations. Whenever you need to
manipulate a different subset (whether disjoint or overlapping), you can
easily define _additional_ blocks. From my experience, this solves most
of the real world problems when n-bit busses are bit banged over GPIOs.
Doesn't this already solve this (in a different way, though)?

Pin direction currently needs to be set up separately, analogous to
requesting gpios. Need to document this better, right. The assumption is
that I/O needs to be efficient primarily, before bloating the API with
direction functions. Or should I add functions for this?

As long as there is no consensus about mainlining this API, I will
maintain it further at

git://git.antcom.de/linux-2.6 blockgpio

because I need it in projects anyway. Will post updates that go in the
direction that you proposed.

Thanks!

Roland
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH RESEND 1/5 v6] gpio: Add a block GPIO API to gpiolib

2012-10-31 Thread Grant Likely
On Sun, Oct 28, 2012 at 9:46 PM, Roland Stigge  wrote:
> The recurring task of providing simultaneous access to GPIO lines (especially
> for bit banging protocols) needs an appropriate API.
>
> This patch adds a kernel internal "Block GPIO" API that enables simultaneous
> access to several GPIOs. This is done by abstracting GPIOs to an n-bit word:
> Once requested, it provides access to a group of GPIOs which can range over
> multiple GPIO chips.
>
> Signed-off-by: Roland Stigge 

Hey Roland,

Linus and I just sat down and talked about your changes. I think I
understand what you need to do, but I've got concerns about the
approach. I'm already not a big fan of the sysfs gpio interface
design*, so you can understand that I'm not keen to extend the
interface further. At the very least, I want to be really careful
about the form that the extension takes.

First off, thank you for writing good documentation. That makes it a
lot easier to understand how the series is intended to be used, and I
really appreciate it.

For the API, I don't think it is a good idea at all to try and
abstract away gpios on multiple controllers. I understand that it
makes life a lot easier for userspace to abstract those details away,
but the problem is that it hides very important information about how
the system is actually constructed that is important to actually get
things to work. For example, say you have a gpio-connected device with
the constraint that GPIOA must change either before or at the same
time as GPIOB, but never after. If those GPIOs are on separate
controllers, then the order is completely undefined, and the user has
no way to control that other than to fall back to manipulating GPIOs
one at a time again (and losing all the performance benefits). Either
controller affinity needs to be explicit in the API, or the API needs
to be constraint oriented (ie. a stream of commands and individual
commands can be coalesced if they meet the constraints**). Also, the
API requires remapping the GPIO numbers which forces the code to be a
lot more complex than it needs to be.

I would rather see new attribute(s) added to the gpiochip's directory
to allow modifying all the pins on a given controller. It's
considerably less complex, and I'm a lot happier about extending the
sysfs ABI in that way than committing to the remapping block approach.

Second, the API appears a little naive in the way it approaches
changing values. It makes the assumption that every gpio in the block
will be written at the same time, which doesn't take into account that
even within a block it is highly likely that only a subset of the
gpios need to be manipulated. A lot of GPIO controllers implement
separate 'set' and 'clear' registers for exactly this reason. The API
needs to allow users to choose a subset for manipulation. The ABI
needs to either have separate 'set' and 'clear' operations, or
operations need to have both mask and value arguments. Similarly, how
do users manipulate pin direction with this ABI?

*The big problem with the sysfs interface is that each operation is
performed on a different file descriptor. While it is convenient for
manipulating gpios from shell scripts, it doesn't provide any good
mechanism to restrict gpios to a specific process or keep track of
which gpios are "opened' by userspace. Ultimately what I think what is
really needed is a proper character device interface that can keep
track of multiple users and who can flip which bits, but that is
slightly out of scope for this discussion.
** Actually, the command stream model is a very interesting idea. It
is worth exploring. It would be a more natural ABI than the multiple
files-and-directories model currently used. It would also eliminate
the problems I have with the sysfs abi while still being usable from
shell script.  :-)

g.
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH RESEND 1/5 v6] gpio: Add a block GPIO API to gpiolib

2012-10-31 Thread Linus Walleij
On Sun, Oct 28, 2012 at 9:46 PM, Roland Stigge  wrote:

Just a quick few things I spotted:

> +struct gpio_block *gpio_block_create(unsigned *gpios, size_t size,
> +const char *name)
> +{
> +   struct gpio_block *block;
> +   struct gpio_block_chip *gbc;
> +   struct gpio_remap *remap;
> +   void *tmp;
> +   int i;
> +
> +   if (size < 1 || size > sizeof(unsigned long) * 8)
> +   return ERR_PTR(-EINVAL);

If the most GPIOs in a block is BITS_PER_LONG, why is the
latter clause not size > BITS_PER_LONG?

Maybe there was some discussion I missed, anyway it deserves
a comment because this looks completely arbitrary.

> +   for (i = 0; i < size; i++)
> +   if (!gpio_is_valid(gpios[i]))
> +   return ERR_PTR(-EINVAL);
> +
> +   block = kzalloc(sizeof(struct gpio_block), GFP_KERNEL);
> +   if (!block)
> +   return ERR_PTR(-ENOMEM);

If these were instead glued to a struct device you could do
devm_kzalloc() here and have it garbage collected.

This is why
https://blueprints.launchpad.net/linux-linaro/+spec/gpiochip-to-dev
needs to happen. (Sorry for hyperlinking.)

> +   block->name = name;
> +   block->ngpio = size;
> +   block->gpio = kzalloc(sizeof(*block->gpio) * size, GFP_KERNEL);
> +   if (!block->gpio)
> +   goto err1;
> +
> +   memcpy(block->gpio, gpios, sizeof(*block->gpio) * size);
> +
> +   for (i = 0; i < size; i++) {
> +   struct gpio_chip *gc = gpio_to_chip(gpios[i]);
> +   int bit = gpios[i] - gc->base;
> +   int index = gpio_block_chip_index(block, gc);
> +
> +   if (index < 0) {
> +   block->nchip++;
> +   tmp = krealloc(block->gbc,
> +  sizeof(struct gpio_block_chip) *
> +  block->nchip, GFP_KERNEL);

Don't do this dynamic array business. Use a linked list instead.

> +   if (!tmp) {
> +   kfree(block->gbc);
> +   goto err2;
> +   }
> +   block->gbc = tmp;
> +   gbc = >gbc[block->nchip - 1];

So this becomes a list traversal and lookup instead.

> +   gbc->gc = gc;
> +   gbc->remap = NULL;
> +   gbc->nremap = 0;
> +   gbc->mask = 0;
> +   } else {
> +   gbc = >gbc[index];

So find it in the list instead.

> +   }
> +   /* represents the mask necessary on calls to the driver's
> +* .get_block() and .set_block()
> +*/
> +   gbc->mask |= BIT(bit);
> +
> +   /* collect gpios that are specified together, represented by
> +* neighboring bits
> +*
> +* Note that even though in setting remap is given a negative
> +* index, the next lines guard that the potential 
> out-of-bounds
> +* pointer is not dereferenced when out of bounds.
> +*/


/*
 * Maybe I'm a bit picky on comment style but I prefer
 * that the first line of a multi-line comment is blank.
 * Applies everywhere.
 */

> +   remap = >remap[gbc->nremap - 1];
> +   if (!gbc->nremap || (bit - i != remap->offset)) {
> +   gbc->nremap++;
> +   tmp = krealloc(gbc->remap,
> + sizeof(struct gpio_remap) *
> + gbc->nremap, GFP_KERNEL);

I don't like this dynamic array either.
Basic pattern: wherever there is a krealloc, use a list.

If lists aren't efficient enough, use some other datastructure, rbtree or
whatever.

> +   if (!tmp) {
> +   kfree(gbc->remap);
> +   goto err3;
> +   }
> +   gbc->remap = tmp;
> +   remap = >remap[gbc->nremap - 1];
> +   remap->offset = bit - i;
> +   remap->mask = 0;
> +   }
> +
> +   /* represents the mask necessary for bit reordering between
> +* gpio_block (i.e. as specified on gpio_block_get() and
> +* gpio_block_set()) and gpio_chip domain (i.e. as specified 
> on
> +* the driver's .set_block() and .get_block())
> +*/
> +   remap->mask |= BIT(i);
> +   }
> +
> +   return block;
> +err3:
> +   for (i = 0; i < block->nchip - 1; i++)
> +   kfree(block->gbc[i].remap);
> +   kfree(block->gbc);
> +err2:
> +   kfree(block->gpio);
> +err1:
> +   kfree(block);
> +   return ERR_PTR(-ENOMEM);
> +}
> +EXPORT_SYMBOL_GPL(gpio_block_create);

Re: [PATCH RESEND 1/5 v6] gpio: Add a block GPIO API to gpiolib

2012-10-31 Thread Linus Walleij
On Sun, Oct 28, 2012 at 9:46 PM, Roland Stigge sti...@antcom.de wrote:

Just a quick few things I spotted:

 +struct gpio_block *gpio_block_create(unsigned *gpios, size_t size,
 +const char *name)
 +{
 +   struct gpio_block *block;
 +   struct gpio_block_chip *gbc;
 +   struct gpio_remap *remap;
 +   void *tmp;
 +   int i;
 +
 +   if (size  1 || size  sizeof(unsigned long) * 8)
 +   return ERR_PTR(-EINVAL);

If the most GPIOs in a block is BITS_PER_LONG, why is the
latter clause not size  BITS_PER_LONG?

Maybe there was some discussion I missed, anyway it deserves
a comment because this looks completely arbitrary.

 +   for (i = 0; i  size; i++)
 +   if (!gpio_is_valid(gpios[i]))
 +   return ERR_PTR(-EINVAL);
 +
 +   block = kzalloc(sizeof(struct gpio_block), GFP_KERNEL);
 +   if (!block)
 +   return ERR_PTR(-ENOMEM);

If these were instead glued to a struct device you could do
devm_kzalloc() here and have it garbage collected.

This is why
https://blueprints.launchpad.net/linux-linaro/+spec/gpiochip-to-dev
needs to happen. (Sorry for hyperlinking.)

 +   block-name = name;
 +   block-ngpio = size;
 +   block-gpio = kzalloc(sizeof(*block-gpio) * size, GFP_KERNEL);
 +   if (!block-gpio)
 +   goto err1;
 +
 +   memcpy(block-gpio, gpios, sizeof(*block-gpio) * size);
 +
 +   for (i = 0; i  size; i++) {
 +   struct gpio_chip *gc = gpio_to_chip(gpios[i]);
 +   int bit = gpios[i] - gc-base;
 +   int index = gpio_block_chip_index(block, gc);
 +
 +   if (index  0) {
 +   block-nchip++;
 +   tmp = krealloc(block-gbc,
 +  sizeof(struct gpio_block_chip) *
 +  block-nchip, GFP_KERNEL);

Don't do this dynamic array business. Use a linked list instead.

 +   if (!tmp) {
 +   kfree(block-gbc);
 +   goto err2;
 +   }
 +   block-gbc = tmp;
 +   gbc = block-gbc[block-nchip - 1];

So this becomes a list traversal and lookup instead.

 +   gbc-gc = gc;
 +   gbc-remap = NULL;
 +   gbc-nremap = 0;
 +   gbc-mask = 0;
 +   } else {
 +   gbc = block-gbc[index];

So find it in the list instead.

 +   }
 +   /* represents the mask necessary on calls to the driver's
 +* .get_block() and .set_block()
 +*/
 +   gbc-mask |= BIT(bit);
 +
 +   /* collect gpios that are specified together, represented by
 +* neighboring bits
 +*
 +* Note that even though in setting remap is given a negative
 +* index, the next lines guard that the potential 
 out-of-bounds
 +* pointer is not dereferenced when out of bounds.
 +*/


/*
 * Maybe I'm a bit picky on comment style but I prefer
 * that the first line of a multi-line comment is blank.
 * Applies everywhere.
 */

 +   remap = gbc-remap[gbc-nremap - 1];
 +   if (!gbc-nremap || (bit - i != remap-offset)) {
 +   gbc-nremap++;
 +   tmp = krealloc(gbc-remap,
 + sizeof(struct gpio_remap) *
 + gbc-nremap, GFP_KERNEL);

I don't like this dynamic array either.
Basic pattern: wherever there is a krealloc, use a list.

If lists aren't efficient enough, use some other datastructure, rbtree or
whatever.

 +   if (!tmp) {
 +   kfree(gbc-remap);
 +   goto err3;
 +   }
 +   gbc-remap = tmp;
 +   remap = gbc-remap[gbc-nremap - 1];
 +   remap-offset = bit - i;
 +   remap-mask = 0;
 +   }
 +
 +   /* represents the mask necessary for bit reordering between
 +* gpio_block (i.e. as specified on gpio_block_get() and
 +* gpio_block_set()) and gpio_chip domain (i.e. as specified 
 on
 +* the driver's .set_block() and .get_block())
 +*/
 +   remap-mask |= BIT(i);
 +   }
 +
 +   return block;
 +err3:
 +   for (i = 0; i  block-nchip - 1; i++)
 +   kfree(block-gbc[i].remap);
 +   kfree(block-gbc);
 +err2:
 +   kfree(block-gpio);
 +err1:
 +   kfree(block);
 +   return ERR_PTR(-ENOMEM);
 +}
 +EXPORT_SYMBOL_GPL(gpio_block_create);
 +
 +void gpio_block_free(struct gpio_block *block)
 +{
 +   int i;
 +
 +   for (i = 0; i  

Re: [PATCH RESEND 1/5 v6] gpio: Add a block GPIO API to gpiolib

2012-10-31 Thread Grant Likely
On Sun, Oct 28, 2012 at 9:46 PM, Roland Stigge sti...@antcom.de wrote:
 The recurring task of providing simultaneous access to GPIO lines (especially
 for bit banging protocols) needs an appropriate API.

 This patch adds a kernel internal Block GPIO API that enables simultaneous
 access to several GPIOs. This is done by abstracting GPIOs to an n-bit word:
 Once requested, it provides access to a group of GPIOs which can range over
 multiple GPIO chips.

 Signed-off-by: Roland Stigge sti...@antcom.de

Hey Roland,

Linus and I just sat down and talked about your changes. I think I
understand what you need to do, but I've got concerns about the
approach. I'm already not a big fan of the sysfs gpio interface
design*, so you can understand that I'm not keen to extend the
interface further. At the very least, I want to be really careful
about the form that the extension takes.

First off, thank you for writing good documentation. That makes it a
lot easier to understand how the series is intended to be used, and I
really appreciate it.

For the API, I don't think it is a good idea at all to try and
abstract away gpios on multiple controllers. I understand that it
makes life a lot easier for userspace to abstract those details away,
but the problem is that it hides very important information about how
the system is actually constructed that is important to actually get
things to work. For example, say you have a gpio-connected device with
the constraint that GPIOA must change either before or at the same
time as GPIOB, but never after. If those GPIOs are on separate
controllers, then the order is completely undefined, and the user has
no way to control that other than to fall back to manipulating GPIOs
one at a time again (and losing all the performance benefits). Either
controller affinity needs to be explicit in the API, or the API needs
to be constraint oriented (ie. a stream of commands and individual
commands can be coalesced if they meet the constraints**). Also, the
API requires remapping the GPIO numbers which forces the code to be a
lot more complex than it needs to be.

I would rather see new attribute(s) added to the gpiochip's directory
to allow modifying all the pins on a given controller. It's
considerably less complex, and I'm a lot happier about extending the
sysfs ABI in that way than committing to the remapping block approach.

Second, the API appears a little naive in the way it approaches
changing values. It makes the assumption that every gpio in the block
will be written at the same time, which doesn't take into account that
even within a block it is highly likely that only a subset of the
gpios need to be manipulated. A lot of GPIO controllers implement
separate 'set' and 'clear' registers for exactly this reason. The API
needs to allow users to choose a subset for manipulation. The ABI
needs to either have separate 'set' and 'clear' operations, or
operations need to have both mask and value arguments. Similarly, how
do users manipulate pin direction with this ABI?

*The big problem with the sysfs interface is that each operation is
performed on a different file descriptor. While it is convenient for
manipulating gpios from shell scripts, it doesn't provide any good
mechanism to restrict gpios to a specific process or keep track of
which gpios are opened' by userspace. Ultimately what I think what is
really needed is a proper character device interface that can keep
track of multiple users and who can flip which bits, but that is
slightly out of scope for this discussion.
** Actually, the command stream model is a very interesting idea. It
is worth exploring. It would be a more natural ABI than the multiple
files-and-directories model currently used. It would also eliminate
the problems I have with the sysfs abi while still being usable from
shell script.  :-)

g.
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH RESEND 1/5 v6] gpio: Add a block GPIO API to gpiolib

2012-10-31 Thread Roland Stigge
Hi Grant,

thank you for your feedback!

Notes below.

On 10/31/2012 04:00 PM, Grant Likely wrote:
 Linus and I just sat down and talked about your changes. I think I
 understand what you need to do, but I've got concerns about the
 approach. I'm already not a big fan of the sysfs gpio interface
 design*, so you can understand that I'm not keen to extend the
 interface further. At the very least, I want to be really careful
 about the form that the extension takes.
 
 First off, thank you for writing good documentation. That makes it a
 lot easier to understand how the series is intended to be used, and I
 really appreciate it.
 
 For the API, I don't think it is a good idea at all to try and
 abstract away gpios on multiple controllers. I understand that it
 makes life a lot easier for userspace to abstract those details away,
 but the problem is that it hides very important information about how
 the system is actually constructed that is important to actually get
 things to work. For example, say you have a gpio-connected device with
 the constraint that GPIOA must change either before or at the same
 time as GPIOB, but never after. If those GPIOs are on separate
 controllers, then the order is completely undefined

It is correct that it's not (yet) well documented and the API is also
not very explicit about it, but the actual approach of the manipulation
order is to let drivers handle gpios as simultaneous as possible and
when not possible, do it in the _order of bits specified_ (either
defined at the device tree level, or when created via
block_gpio_create() directly).

I consider it a good thing to abstract things away if possible here, if
it is well documented what actually happens, which info should be
available from the definition and the possibilities of the drivers and
hardware actually used (the optional block gpio interface must be well
implemented in the respective driver, and when combining multiple gpio
controller chips, it should be clear that certain realtime timings on a
resulting virtual n-bit bus are not possible.)

 Second, the API appears a little naive in the way it approaches
 changing values. It makes the assumption that every gpio in the block
 will be written at the same time, which doesn't take into account that
 even within a block it is highly likely that only a subset of the
 gpios need to be manipulated. A lot of GPIO controllers implement
 separate 'set' and 'clear' registers for exactly this reason. The API
 needs to allow users to choose a subset for manipulation. The ABI
 needs to either have separate 'set' and 'clear' operations, or
 operations need to have both mask and value arguments. Similarly, how
 do users manipulate pin direction with this ABI?

I'm not sure how far you tested the API in depth: You can already define
a block that maps onto a subset of gpios on a controller and internally
of course maps onto those set and clear operations. Whenever you need to
manipulate a different subset (whether disjoint or overlapping), you can
easily define _additional_ blocks. From my experience, this solves most
of the real world problems when n-bit busses are bit banged over GPIOs.
Doesn't this already solve this (in a different way, though)?

Pin direction currently needs to be set up separately, analogous to
requesting gpios. Need to document this better, right. The assumption is
that I/O needs to be efficient primarily, before bloating the API with
direction functions. Or should I add functions for this?

As long as there is no consensus about mainlining this API, I will
maintain it further at

git://git.antcom.de/linux-2.6 blockgpio

because I need it in projects anyway. Will post updates that go in the
direction that you proposed.

Thanks!

Roland
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH RESEND 1/5 v6] gpio: Add a block GPIO API to gpiolib

2012-10-31 Thread Roland Stigge
Hi Linus,

thanks for your notes, comments below:

On 10/31/2012 03:06 PM, Linus Walleij wrote:
 +struct gpio_block *gpio_block_create(unsigned *gpios, size_t size,
 +const char *name)
 +{
 +   struct gpio_block *block;
 +   struct gpio_block_chip *gbc;
 +   struct gpio_remap *remap;
 +   void *tmp;
 +   int i;
 +
 +   if (size  1 || size  sizeof(unsigned long) * 8)
 +   return ERR_PTR(-EINVAL);
 
 If the most GPIOs in a block is BITS_PER_LONG, why is the
 latter clause not size  BITS_PER_LONG?

Good catch, thanks! :-)

 +   for (i = 0; i  size; i++)
 +   if (!gpio_is_valid(gpios[i]))
 +   return ERR_PTR(-EINVAL);
 +
 +   block = kzalloc(sizeof(struct gpio_block), GFP_KERNEL);
 +   if (!block)
 +   return ERR_PTR(-ENOMEM);
 
 If these were instead glued to a struct device you could do
 devm_kzalloc() here and have it garbage collected.

Good, will do.

 This is why
 https://blueprints.launchpad.net/linux-linaro/+spec/gpiochip-to-dev
 needs to happen. (Sorry for hyperlinking.)
 
 +   block-name = name;
 +   block-ngpio = size;
 +   block-gpio = kzalloc(sizeof(*block-gpio) * size, GFP_KERNEL);
 +   if (!block-gpio)
 +   goto err1;
 +
 +   memcpy(block-gpio, gpios, sizeof(*block-gpio) * size);
 +
 +   for (i = 0; i  size; i++) {
 +   struct gpio_chip *gc = gpio_to_chip(gpios[i]);
 +   int bit = gpios[i] - gc-base;
 +   int index = gpio_block_chip_index(block, gc);
 +
 +   if (index  0) {
 +   block-nchip++;
 +   tmp = krealloc(block-gbc,
 +  sizeof(struct gpio_block_chip) *
 +  block-nchip, GFP_KERNEL);
 
 Don't do this dynamic array business. Use a linked list instead.

OK, I checked the important spots where access to the two lists (gbc and
remap) happen (set and get functions), and the access is always
sequential, monotonic. So will use lists. Thanks.

 [...]
 /*
  * Maybe I'm a bit picky on comment style but I prefer
  * that the first line of a multi-line comment is blank.
  * Applies everywhere.
  */

As noted earlier in the discussion, current gpiolib.c's convention is
done first-line-not-blank. So I sticked to this (un)convention. But can
change this - you are not the first one pointing this out. :-)

 +   if (!tmp) {
 +   kfree(gbc-remap);
 +   goto err3;
 +   }
 +   gbc-remap = tmp;
 +   remap = gbc-remap[gbc-nremap - 1];
 +   remap-offset = bit - i;
 +   remap-mask = 0;
 +   }
 +
 +   /* represents the mask necessary for bit reordering between
 +* gpio_block (i.e. as specified on gpio_block_get() and
 +* gpio_block_set()) and gpio_chip domain (i.e. as specified 
 on
 +* the driver's .set_block() and .get_block())
 +*/
 +   remap-mask |= BIT(i);
 +   }
 +
 +   return block;
 +err3:
 +   for (i = 0; i  block-nchip - 1; i++)
 +   kfree(block-gbc[i].remap);
 +   kfree(block-gbc);
 +err2:
 +   kfree(block-gpio);
 +err1:
 +   kfree(block);
 +   return ERR_PTR(-ENOMEM);
 +}
 +EXPORT_SYMBOL_GPL(gpio_block_create);
 +
 +void gpio_block_free(struct gpio_block *block)
 +{
 +   int i;
 +
 +   for (i = 0; i  block-nchip; i++)
 +   kfree(block-gbc[i].remap);
 +   kfree(block-gpio);
 +   kfree(block-gbc);
 +   kfree(block);
 +}
 +EXPORT_SYMBOL_GPL(gpio_block_free);
 
 So if we only had a real struct device  inside the gpiochip all
 this boilerplate would go away, as devm_* take care of releasing
 the resources.

Right. I guess you mean struct gpio_block here which should have a dev?
(Having gpiochip as a dev also would be best, though.) :-)

We need a separate dev for struct gpio_block, since those can be defined
dynamically (i.e. often) during the lifespan of gpio and gpiochip, so
garbage collection would be deferred for too long.

Thanks,

Roland
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH RESEND 1/5 v6] gpio: Add a block GPIO API to gpiolib

2012-10-31 Thread Grant Likely
Hi Roland

On Wed, Oct 31, 2012 at 6:19 PM, Roland Stigge sti...@antcom.de wrote:
 On 10/31/2012 04:00 PM, Grant Likely wrote:
 For the API, I don't think it is a good idea at all to try and
 abstract away gpios on multiple controllers. I understand that it
 makes life a lot easier for userspace to abstract those details away,
 but the problem is that it hides very important information about how
 the system is actually constructed that is important to actually get
 things to work. For example, say you have a gpio-connected device with
 the constraint that GPIOA must change either before or at the same
 time as GPIOB, but never after. If those GPIOs are on separate
 controllers, then the order is completely undefined

 It is correct that it's not (yet) well documented and the API is also
 not very explicit about it, but the actual approach of the manipulation
 order is to let drivers handle gpios as simultaneous as possible and
 when not possible, do it in the _order of bits specified_ (either
 defined at the device tree level, or when created via
 block_gpio_create() directly).

The documentation is actually fine. I do understand that the intent is
as simultaneous as possible, but I accept the point that the order
of specification affects the behaviour*. However, it still remains
that the method used by the ABI abstracts at the wrong level and that
blocking arbitrary GPIO pins into a single virtual GPIO register is a
bad idea.

*note that the current code doesn't implement that intended behaviour
either since the gpios are processed in the order of the controllers,
not the order of the bits.

 I'm not sure how far you tested the API in depth: You can already define
 a block that maps onto a subset of gpios on a controller and internally
 of course maps onto those set and clear operations. Whenever you need to
 manipulate a different subset (whether disjoint or overlapping), you can
 easily define _additional_ blocks. From my experience, this solves most
 of the real world problems when n-bit busses are bit banged over GPIOs.
 Doesn't this already solve this (in a different way, though)?

Blech! Requiring a new block for each possible combination of
write-at-once bits is a horrible ABI. That just strengthens my opinion
that the abstraction isn't right yet.

 Pin direction currently needs to be set up separately, analogous to
 requesting gpios. Need to document this better, right. The assumption is
 that I/O needs to be efficient primarily, before bloating the API with
 direction functions. Or should I add functions for this?

Since this is a userspace facing ABI, once it is merged it cannot be
changed in an incompatible way. I cannot merge it until there is at
least a plan for how to handle all of the reasonable use cases. That
means it must support set/clear or mask operations. Also, if it sticks
with the design of grouping pins from multiple controllers, then it
needs to handle explicitly constraining what order operations are
performed in at the time of the operation. At the time of setup
doesn't work since constraints between pins may not always be in the
same order.

I really think you should consider implementing a command stream type
of interface.

g.
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH RESEND 1/5 v6] gpio: Add a block GPIO API to gpiolib

2012-10-31 Thread Mark Brown
On Wed, Oct 31, 2012 at 04:00:17PM +0100, Grant Likely wrote:

 For the API, I don't think it is a good idea at all to try and
 abstract away gpios on multiple controllers. I understand that it
 makes life a lot easier for userspace to abstract those details away,
 but the problem is that it hides very important information about how
 the system is actually constructed that is important to actually get
 things to work. For example, say you have a gpio-connected device with
 the constraint that GPIOA must change either before or at the same
 time as GPIOB, but never after. If those GPIOs are on separate
 controllers, then the order is completely undefined, and the user has
 no way to control that other than to fall back to manipulating GPIOs
 one at a time again (and losing all the performance benefits). Either
 controller affinity needs to be explicit in the API, or the API needs
 to be constraint oriented (ie. a stream of commands and individual
 commands can be coalesced if they meet the constraints**). Also, the
 API requires remapping the GPIO numbers which forces the code to be a
 lot more complex than it needs to be.

It feels like I'm missing something here but can we not simply say that
if the user cares about the ordering of the signal changes within an
update then they should be doing two separate updates?  Most of the
cases I'm aware of do things as an update with a strobe or clock that
latches the values.

The big advantage of grouping things together is that it means that we
centralise the fallback code.

 I would rather see new attribute(s) added to the gpiochip's directory
 to allow modifying all the pins on a given controller. It's
 considerably less complex, and I'm a lot happier about extending the
 sysfs ABI in that way than committing to the remapping block approach.

When I've looked at this stuff I've only looked at and thought about in
kernel users.  The gpiolib sysfs ABI is already fun enough :)
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH RESEND 1/5 v6] gpio: Add a block GPIO API to gpiolib

2012-10-28 Thread Roland Stigge
The recurring task of providing simultaneous access to GPIO lines (especially
for bit banging protocols) needs an appropriate API.

This patch adds a kernel internal "Block GPIO" API that enables simultaneous
access to several GPIOs. This is done by abstracting GPIOs to an n-bit word:
Once requested, it provides access to a group of GPIOs which can range over
multiple GPIO chips.

Signed-off-by: Roland Stigge 
---

 Documentation/gpio.txt |   47 +
 drivers/gpio/gpiolib.c |  217 +
 include/asm-generic/gpio.h |   15 +++
 include/linux/gpio.h   |   74 +++
 4 files changed, 353 insertions(+)

--- linux-2.6.orig/Documentation/gpio.txt
+++ linux-2.6/Documentation/gpio.txt
@@ -439,6 +439,53 @@ slower clock delays the rising edge of S
 signaling rate accordingly.
 
 
+Block GPIO
+--
+
+The above described interface concentrates on handling single GPIOs.  However,
+in applications where it is critical to set several GPIOs at once, this
+interface doesn't work well, e.g. bit-banging protocols via grouped GPIO lines.
+Consider a GPIO controller that is connected via a slow I2C line. When
+switching two or more GPIOs one after another, there can be considerable time
+between those events. This is solved by an interface called Block GPIO:
+
+struct gpio_block *gpio_block_create(unsigned int *gpios, size_t size);
+
+This creates a new block of GPIOs as a list of GPIO numbers with the specified
+size which are accessible via the returned struct gpio_block and the accessor
+functions described below. Please note that you need to request the GPIOs
+separately via gpio_request(). An arbitrary list of globally valid GPIOs can be
+specified, even ranging over several gpio_chips. Actual handling of I/O
+operations will be done on a best effort base, i.e. simultaneous I/O only where
+possible by hardware and implemented in the respective GPIO driver. The number
+of GPIOs in one block is limited to the number of bits in an unsigned long, or
+BITS_PER_LONG, of the respective platform, i.e. typically at least 32 on a 32
+bit system, and at least 64 on a 64 bit system. However, several blocks can be
+defined at once.
+
+unsigned gpio_block_get(struct gpio_block *block);
+void gpio_block_set(struct gpio_block *block, unsigned value);
+
+With those accessor functions, setting and getting the GPIO values is possible,
+analogous to gpio_get_value() and gpio_set_value(). Each bit in the return
+value of gpio_block_get() and in the value argument of gpio_block_set()
+corresponds to a bit specified on gpio_block_create(). Block operations in
+hardware are only possible where the respective GPIO driver implements it,
+falling back to using single GPIO operations where the driver only implements
+single GPIO access.
+
+void gpio_block_free(struct gpio_block *block);
+
+After the GPIO block isn't used anymore, it should be free'd via
+gpio_block_free().
+
+int gpio_block_register(struct gpio_block *block);
+void gpio_block_unregister(struct gpio_block *block);
+
+These functions can be used to register a GPIO block. Blocks registered this
+way will be available via sysfs.
+
+
 What do these conventions omit?
 ===
 One of the biggest things these conventions omit is pin multiplexing, since
--- linux-2.6.orig/drivers/gpio/gpiolib.c
+++ linux-2.6/drivers/gpio/gpiolib.c
@@ -83,6 +83,8 @@ static inline void desc_set_label(struct
 #endif
 }
 
+static LIST_HEAD(gpio_block_list);
+
 /* Warn when drivers omit gpio_request() calls -- legal but ill-advised
  * when setting direction, and otherwise illegal.  Until board setup code
  * and drivers use explicit requests everywhere (which won't happen when
@@ -1676,6 +1678,221 @@ void __gpio_set_value(unsigned gpio, int
 }
 EXPORT_SYMBOL_GPL(__gpio_set_value);
 
+static int gpio_block_chip_index(struct gpio_block *block, struct gpio_chip 
*gc)
+{
+   int i;
+
+   for (i = 0; i < block->nchip; i++) {
+   if (block->gbc[i].gc == gc)
+   return i;
+   }
+   return -1;
+}
+
+struct gpio_block *gpio_block_create(unsigned *gpios, size_t size,
+const char *name)
+{
+   struct gpio_block *block;
+   struct gpio_block_chip *gbc;
+   struct gpio_remap *remap;
+   void *tmp;
+   int i;
+
+   if (size < 1 || size > sizeof(unsigned long) * 8)
+   return ERR_PTR(-EINVAL);
+
+   for (i = 0; i < size; i++)
+   if (!gpio_is_valid(gpios[i]))
+   return ERR_PTR(-EINVAL);
+
+   block = kzalloc(sizeof(struct gpio_block), GFP_KERNEL);
+   if (!block)
+   return ERR_PTR(-ENOMEM);
+
+   block->name = name;
+   block->ngpio = size;
+   block->gpio = kzalloc(sizeof(*block->gpio) * size, GFP_KERNEL);
+   if (!block->gpio)
+   goto err1;
+
+   memcpy(block->gpio, gpios, sizeof(*block->gpio) * size);
+
+   for (i = 

[PATCH RESEND 1/5 v6] gpio: Add a block GPIO API to gpiolib

2012-10-28 Thread Roland Stigge
The recurring task of providing simultaneous access to GPIO lines (especially
for bit banging protocols) needs an appropriate API.

This patch adds a kernel internal Block GPIO API that enables simultaneous
access to several GPIOs. This is done by abstracting GPIOs to an n-bit word:
Once requested, it provides access to a group of GPIOs which can range over
multiple GPIO chips.

Signed-off-by: Roland Stigge sti...@antcom.de
---

 Documentation/gpio.txt |   47 +
 drivers/gpio/gpiolib.c |  217 +
 include/asm-generic/gpio.h |   15 +++
 include/linux/gpio.h   |   74 +++
 4 files changed, 353 insertions(+)

--- linux-2.6.orig/Documentation/gpio.txt
+++ linux-2.6/Documentation/gpio.txt
@@ -439,6 +439,53 @@ slower clock delays the rising edge of S
 signaling rate accordingly.
 
 
+Block GPIO
+--
+
+The above described interface concentrates on handling single GPIOs.  However,
+in applications where it is critical to set several GPIOs at once, this
+interface doesn't work well, e.g. bit-banging protocols via grouped GPIO lines.
+Consider a GPIO controller that is connected via a slow I2C line. When
+switching two or more GPIOs one after another, there can be considerable time
+between those events. This is solved by an interface called Block GPIO:
+
+struct gpio_block *gpio_block_create(unsigned int *gpios, size_t size);
+
+This creates a new block of GPIOs as a list of GPIO numbers with the specified
+size which are accessible via the returned struct gpio_block and the accessor
+functions described below. Please note that you need to request the GPIOs
+separately via gpio_request(). An arbitrary list of globally valid GPIOs can be
+specified, even ranging over several gpio_chips. Actual handling of I/O
+operations will be done on a best effort base, i.e. simultaneous I/O only where
+possible by hardware and implemented in the respective GPIO driver. The number
+of GPIOs in one block is limited to the number of bits in an unsigned long, or
+BITS_PER_LONG, of the respective platform, i.e. typically at least 32 on a 32
+bit system, and at least 64 on a 64 bit system. However, several blocks can be
+defined at once.
+
+unsigned gpio_block_get(struct gpio_block *block);
+void gpio_block_set(struct gpio_block *block, unsigned value);
+
+With those accessor functions, setting and getting the GPIO values is possible,
+analogous to gpio_get_value() and gpio_set_value(). Each bit in the return
+value of gpio_block_get() and in the value argument of gpio_block_set()
+corresponds to a bit specified on gpio_block_create(). Block operations in
+hardware are only possible where the respective GPIO driver implements it,
+falling back to using single GPIO operations where the driver only implements
+single GPIO access.
+
+void gpio_block_free(struct gpio_block *block);
+
+After the GPIO block isn't used anymore, it should be free'd via
+gpio_block_free().
+
+int gpio_block_register(struct gpio_block *block);
+void gpio_block_unregister(struct gpio_block *block);
+
+These functions can be used to register a GPIO block. Blocks registered this
+way will be available via sysfs.
+
+
 What do these conventions omit?
 ===
 One of the biggest things these conventions omit is pin multiplexing, since
--- linux-2.6.orig/drivers/gpio/gpiolib.c
+++ linux-2.6/drivers/gpio/gpiolib.c
@@ -83,6 +83,8 @@ static inline void desc_set_label(struct
 #endif
 }
 
+static LIST_HEAD(gpio_block_list);
+
 /* Warn when drivers omit gpio_request() calls -- legal but ill-advised
  * when setting direction, and otherwise illegal.  Until board setup code
  * and drivers use explicit requests everywhere (which won't happen when
@@ -1676,6 +1678,221 @@ void __gpio_set_value(unsigned gpio, int
 }
 EXPORT_SYMBOL_GPL(__gpio_set_value);
 
+static int gpio_block_chip_index(struct gpio_block *block, struct gpio_chip 
*gc)
+{
+   int i;
+
+   for (i = 0; i  block-nchip; i++) {
+   if (block-gbc[i].gc == gc)
+   return i;
+   }
+   return -1;
+}
+
+struct gpio_block *gpio_block_create(unsigned *gpios, size_t size,
+const char *name)
+{
+   struct gpio_block *block;
+   struct gpio_block_chip *gbc;
+   struct gpio_remap *remap;
+   void *tmp;
+   int i;
+
+   if (size  1 || size  sizeof(unsigned long) * 8)
+   return ERR_PTR(-EINVAL);
+
+   for (i = 0; i  size; i++)
+   if (!gpio_is_valid(gpios[i]))
+   return ERR_PTR(-EINVAL);
+
+   block = kzalloc(sizeof(struct gpio_block), GFP_KERNEL);
+   if (!block)
+   return ERR_PTR(-ENOMEM);
+
+   block-name = name;
+   block-ngpio = size;
+   block-gpio = kzalloc(sizeof(*block-gpio) * size, GFP_KERNEL);
+   if (!block-gpio)
+   goto err1;
+
+   memcpy(block-gpio, gpios, sizeof(*block-gpio) * size);
+
+   for (i =