Thread (138 messages) 138 messages, 6 authors, 2013-10-25

Re: [PATCH 01/03] Make non-linear GPIO ranges accesible from gpiolib

From: Linus Walleij <hidden>
Date: 2013-10-09 14:01:08
Also in: lkml

On Wed, Oct 9, 2013 at 3:28 PM, Christian Ruppert
[off-list ref] wrote:
On Wed, Oct 09, 2013 at 01:58:35PM +0200, Linus Walleij wrote:
quoted
On Tue, Oct 8, 2013 at 2:25 PM, Christian Ruppert
[off-list ref] wrote:
quoted
+In addition, named groups of pins can be mapped to pin groups of a given
+pin controller using the gpio-ranges property as described below:
+
+       gpio-range-list ::= <single-gpio-range> [gpio-range-list]
+       single-gpio-range ::= <numeric-gpio-range> | <named-gpio-range>
+       numeric-gpio-range ::=
+                       <pinctrl-phandle> <gpio-base> <pinctrl-base> <count>
+       named-gpio-range ::= <pinctrl-phandle> <gpio-base> '<0 0>'
+       pinctrl-phanle : phandle to pin controller node.
phanle really?
Yes, this is actually identical to the numeric ranges. It specifies the
pin controller which is "responsible" for the pins/pin group in
question.
I was more thinking about the speling, should it not be "phandle"?
The named pin groups actually are a physical property of the pin
controller hardware (well, at least the pin groups are, the names are
not ;).
OK.

It would be good if the names of the group could match, as close
as possible, the names given to the same identity in the data
sheet or similar documentation.
Obviously, a driver (no matter for which OS) must be aware of
this hardware property so it can decide which value to write to which
register in order to control the pin mux. If we don't want to split (or
worse: duplicate) that information in the driver and device tree, I see
two alternatives.
1. Define register offsets, masks and register values and the list of
   pins controlled by those register/value pairs in the device tree.
This is not a viable alternative of course.
2. Define register offsets, masks and register values and the list of
   pins controlled by those register/value pairs in the drivers. Define
   a portable high level interface for the device tree.

My personal preference is clearly 2.
Yes you are also making a very good case for it, and I tend to
think the same.

But alt 1 is not the alternative, the alternative (3) is to reference
the pin numbers in the device tree, if need be by a largeish
set of one-pin-per-range ranges if these are disparate.

Which is arguably quite ugly compared to (2) as well, but atleast
reasonable.
quoted
Are you sure this is useable on Windows and OpenBSD without
first verbatim copying the structure of the Linux pinctrl driver?
Without knowing the pinctrl infrastructure in either Windows or OpenBSD,
I am actually convinced that this is _more_ portable than the numeric
ranges:

- The numeric ranges used today depend on a numbering scheme which
  is specific to the Linux pinctrl framework.
Not really, it's just a number, it is quite possible for driver developers
to have this match an index number from the hardware documentation.
Also these numbers are sparse, they don't have to be an array that
begin with 0 and go to N. So *any* discrete numbering scheme will
do, and it's not any more strange than the named groups, instead of
putting five apples in a basket and labeling it "group" you can number
the five apples { 7, 19, 22, 67, 216 } and say each one belongs in
the basket.
One could very well
  imagine pinctrl frameworks without any numbering scheme at all.
Whether numbers or text labels are used to label the physical
entities does not matter, what matters is that the device tree
binding documentation is implementable by several OS:es.
- The actual numbers depend on the particulars of each individual Linux
  pinctrl driver implementation.
No, not from a device tree point of view. It is possible to select
a numbering scheme coming from the device tree and use that
in the driver instead of the other way around.

Do not always assume that the driver comes first. It is possible
to enumerate the pins in a DT binding and tree before even starting
to implement the driver, and the pinctrl framework will cope with
whatever number scheme you choose.
Adding the higher level concept of named pin groups (which accidentally
exists in Linux already) seems to be an elegant path to better
portability here.
Same same, but it deals with sets of pins instead of individual
pins.
quoted
Empty group names for "anonymous" groups (I guess these become
linear then?) is really looking strange. They are empty strings with
a semantic effect, that is quite disturbing. but I don't know a better
way either.
The alternative would probably be to skip them altogether but I'm afraid
that that makes it even worse...
We'll have to live with this...
quoted
quoted
diff --git a/drivers/pinctrl/core.c b/drivers/pinctrl/core.c
index 2a00239..52e2e6f 100644
--- a/drivers/pinctrl/core.c
+++ b/drivers/pinctrl/core.c
@@ -456,6 +456,29 @@ struct pinctrl_dev *pinctrl_find_and_add_gpio_range(const char *devname,
 }
 EXPORT_SYMBOL_GPL(pinctrl_find_and_add_gpio_range);

+int pinctrl_add_gpio_pingrp_range(struct pinctrl_dev *pctldev,
+                               struct pinctrl_gpio_range *range,
+                               char *pin_group)
+{
+       const struct pinctrl_ops *pctlops = pctldev->desc->pctlops;
+       int group_selector, ret;
+
+       group_selector = pinctrl_get_group_selector(pctldev, pin_group);
+       if (group_selector < 0)
+               return group_selector;
+
+       ret = pctlops->get_group_pins(pctldev, group_selector,
+                               &range->pins,
+                               &range->npins);
+       if (ret < 0)
+               return ret;
+
+       pinctrl_add_gpio_range(pctldev, range);
+       return 0;
+
+}
+EXPORT_SYMBOL_GPL(pinctrl_add_gpio_pingrp_range);
I don't think this is very elegant. It's quite strange that the range partly
populated from the GPIO side gets the corresponding pins filled
in by this function. Can't we think about something more elegant?
It reflects the strangeness I'm reacting to above I guess.
I don't see in which respect the existence of this function is different
from the existence of pinctrl_find_and_add_gpio_range (the sole purpose
of which is to be called from gpiochip_add_pin_range). I like the idea
of being strict about the gpio framework only managing GPIO related
things and the pinctrl framework only managing pinctrl related things.
Thus, I adopted this concept to gpiochip_add_pingroup_range (which calls
pinctrl_add_gpio_pingrp_range).

Tell me if you want me to migrate the get_group_pins call to
gpiochip_add_pingroup_range but IMHO this would be less elegant.
Hm there are several ways to skin this cat but well, this is OK.

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