diff mbox series

[RFC,1/3] dt-bindings: pinctrl: sunxi: document new generic binding

Message ID 20171113012523.2328-2-andre.przywara@arm.com
State New
Headers show
Series pinctrl: sunxi: Add DT-based generic pinctrl driver | expand

Commit Message

Andre Przywara Nov. 13, 2017, 1:25 a.m. UTC
So far all the Allwinner pinctrl drivers provided a table in the
kernel to describe all the pins and the link between the pinctrl functions
names (strings) and their respective mux values (register values).

Extend the binding to put those mappings in the DT, so that any SoC can
describe its pinctrl and GPIO data fully there instead of relying on
tables.
This uses a generic compatible name, to be prepended with an SoC
specific name in the node.

Signed-off-by: Andre Przywara <andre.przywara@arm.com>
---
 .../bindings/pinctrl/allwinner,sunxi-pinctrl.txt   | 58 ++++++++++++++++++++++
 1 file changed, 58 insertions(+)

Comments

Rob Herring Nov. 20, 2017, 6:52 p.m. UTC | #1
On Mon, Nov 13, 2017 at 01:25:21AM +0000, Andre Przywara wrote:
> So far all the Allwinner pinctrl drivers provided a table in the
> kernel to describe all the pins and the link between the pinctrl functions
> names (strings) and their respective mux values (register values).
> 
> Extend the binding to put those mappings in the DT, so that any SoC can
> describe its pinctrl and GPIO data fully there instead of relying on
> tables.
> This uses a generic compatible name, to be prepended with an SoC
> specific name in the node.
> 
> Signed-off-by: Andre Przywara <andre.przywara@arm.com>
> ---
>  .../bindings/pinctrl/allwinner,sunxi-pinctrl.txt   | 58 ++++++++++++++++++++++
>  1 file changed, 58 insertions(+)

I'm leaving this one to Linus...

Generally, this has not been the direction we've wanted to go. What 
makes this unique to Allwinner?

Rob
--
To unsubscribe from this list: send the line "unsubscribe linux-gpio" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Linus Walleij Nov. 24, 2017, 10:19 a.m. UTC | #2
On Mon, Nov 13, 2017 at 2:25 AM, Andre Przywara <andre.przywara@arm.com> wrote:

> So far all the Allwinner pinctrl drivers provided a table in the
> kernel to describe all the pins and the link between the pinctrl functions
> names (strings) and their respective mux values (register values).
>
> Extend the binding to put those mappings in the DT, so that any SoC can
> describe its pinctrl and GPIO data fully there instead of relying on
> tables.
> This uses a generic compatible name, to be prepended with an SoC
> specific name in the node.
>
> Signed-off-by: Andre Przywara <andre.przywara@arm.com>
(...)

I definately want feedback from Maxime before I do anything with
this patch series.

> +** Generic pinctrl binding
> +The above binding requires knowledge of the actual mux setting values for
> +each supported SoC in the code parsing the DT (for instance the kernel).
> +The generic binding puts this information in the DT. It uses the
> +"allwinner,sunxi-pinctrl" compatible, in addition to some SoC specific string.
> +It extends the above described binding as follows:
> +Required properties:
> +- allwinner,gpio-pins: An array of 32-bit numbers to denote the number of
> +  implemented pins per pin controller port. Non-implemented ports can specify
> +  0 here. There will be as many ports as this array has elements.

I don't understand what this adds that gpio-ranges does not already
provide.
Documentation/devicetree/bindings/gpio/gpio.txt
at the end of the file.

These ranges exist exactly to map pin controller pins in a pin controller
to GPIO lines in a gpiochip.

> +- allwinner,irq-pin-map: Contains a number of IRQ port maps, describing the
> +  relationship between interrupt banks and GPIO pins. Each map has six 32-bit
> +  members:
> +  <[IRQ port] [1st IRQ pin] [GPIO port] [1st GPIO pin] [mux value] [length]>
> +  This maps the first [length] IRQ pins starting with [IRQ port]:[1st IRQ pin]
> +  to [GPIO port]:[1st GPIO pin], all using [mux value] to select the IRQ
> +  functionality.

We have recently added GPIO "bank" awareness into gpiolib
via Thierry Reding's patches, so a gpiochip can use the generic
GPIOLIB_IRQCHIP and specify multiple IRQ parents with a map.

Please see if you can use this instead.

If any of this should be expressed in the DT bindings it should
be genericized and not use any "allwinner,*" prefixes, and it
should preferably just be hard-coded in the driver and switched
in from the compatible string IMO.

> +Optional properties:
> +- allwinner,port-base: The number of GPIO ports to skip at the beginning.
> +- allwinner,irq-bank-base: The number of IRQ banks to skip at the beginning.

I don't understand this. It looks hacky. Can you elaborate why this
is needed?

> +- allwinner,irq-read-needs-mux: Specifies that reading the line level of
> +  a pin configured as an IRQ pin is not possible. A driver needs to switch
> +  to the GPIO-in function to be able to read the level.

I guess it is a bool flag?

> +Required properties for subnodes:
> +- pinmux: An array of mux values to write into the respective MMIO register
> +  bits for this pin when selecting the function. If this array has less
> +  elements than pins, the *last* value will be used for all pins beyond that.
> +  This allows to use a single element for the (likely) case all pins use the
> +  same mux value.

This is a standard bindings so I don't have much against it. But I
need Maxime's input here, I think we should keep Allwinner consistent
across SoCs.

Yours,
Linus Walleij
--
To unsubscribe from this list: send the line "unsubscribe linux-gpio" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Thierry Reding Nov. 24, 2017, 10:52 a.m. UTC | #3
On Fri, Nov 24, 2017 at 11:19:52AM +0100, Linus Walleij wrote:
> On Mon, Nov 13, 2017 at 2:25 AM, Andre Przywara <andre.przywara@arm.com> wrote:
> 
> > So far all the Allwinner pinctrl drivers provided a table in the
> > kernel to describe all the pins and the link between the pinctrl functions
> > names (strings) and their respective mux values (register values).
> >
> > Extend the binding to put those mappings in the DT, so that any SoC can
> > describe its pinctrl and GPIO data fully there instead of relying on
> > tables.
> > This uses a generic compatible name, to be prepended with an SoC
> > specific name in the node.

This seems backwards to me. I'm not sure if Rob has any hard rules on
this, but in the past I've seen a lot of drivers stick this kind of data
into drivers. I personally also prefer that approach because the data is
completely static and there's no way for any specific board to customize
it. So the tables are in fact implied completely by the SoC compatible
string.

Moving all of this data into device tree has a number of disadvantages:

  * Existing boards already use the static tables in the driver, and the
    device trees don't contain any data, so you can't get rid of any of
    the existing tables because it would break ABI.

  * Moving the table into the DT doesn't actually solve anything because
    the driver would have to validate the DT description to make sure it
    contains valid data. And in order to validate DT content, the driver
    would need a copy of the table anyway.

I don't think you're going to do yourself any favours by pushing this. I
also don't see the commit description give any reason why you want to
move the table into device tree. Do you see any advantages in doing so?

Thierry
Andre Przywara Nov. 24, 2017, 11:58 a.m. UTC | #4
Hi Linus,

thanks for having a look!

On 24/11/17 10:19, Linus Walleij wrote:
> On Mon, Nov 13, 2017 at 2:25 AM, Andre Przywara <andre.przywara@arm.com> wrote:
> 
>> So far all the Allwinner pinctrl drivers provided a table in the
>> kernel to describe all the pins and the link between the pinctrl functions
>> names (strings) and their respective mux values (register values).
>>
>> Extend the binding to put those mappings in the DT, so that any SoC can
>> describe its pinctrl and GPIO data fully there instead of relying on
>> tables.
>> This uses a generic compatible name, to be prepended with an SoC
>> specific name in the node.
>>
>> Signed-off-by: Andre Przywara <andre.przywara@arm.com>
> (...)
> 
> I definately want feedback from Maxime before I do anything with
> this patch series.
> 
>> +** Generic pinctrl binding
>> +The above binding requires knowledge of the actual mux setting values for
>> +each supported SoC in the code parsing the DT (for instance the kernel).
>> +The generic binding puts this information in the DT. It uses the
>> +"allwinner,sunxi-pinctrl" compatible, in addition to some SoC specific string.
>> +It extends the above described binding as follows:
>> +Required properties:
>> +- allwinner,gpio-pins: An array of 32-bit numbers to denote the number of
>> +  implemented pins per pin controller port. Non-implemented ports can specify
>> +  0 here. There will be as many ports as this array has elements.
> 
> I don't understand what this adds that gpio-ranges does not already
> provide.
> Documentation/devicetree/bindings/gpio/gpio.txt
> at the end of the file.

Ah, thanks for the pointer, will try to see if that fits in here.
Although here (despite my clumsy naming) I think this is more about the
"pinmux" pins than the GPIOs. I am not sure if it's just my
understanding or if on Allwinner we just happen to have every pinmux pin
being a GPIO pin as well, so the distinction between the two isn't so clear.

> These ranges exist exactly to map pin controller pins in a pin controller
> to GPIO lines in a gpiochip.

Which makes it a bit more confusing because we have the pinctrl and GPIO
controller drivers combined in one file.

>> +- allwinner,irq-pin-map: Contains a number of IRQ port maps, describing the
>> +  relationship between interrupt banks and GPIO pins. Each map has six 32-bit
>> +  members:
>> +  <[IRQ port] [1st IRQ pin] [GPIO port] [1st GPIO pin] [mux value] [length]>
>> +  This maps the first [length] IRQ pins starting with [IRQ port]:[1st IRQ pin]
>> +  to [GPIO port]:[1st GPIO pin], all using [mux value] to select the IRQ
>> +  functionality.
> 
> We have recently added GPIO "bank" awareness into gpiolib
> via Thierry Reding's patches, so a gpiochip can use the generic
> GPIOLIB_IRQCHIP and specify multiple IRQ parents with a map.
> 
> Please see if you can use this instead.

Thanks for the hint, will have a look.

> If any of this should be expressed in the DT bindings it should
> be genericized and not use any "allwinner,*" prefixes, and it
> should preferably just be hard-coded in the driver and switched
> in from the compatible string IMO.

I agree, this allwinner prefix was just a first shot for the RFC.

The reason for this map is that older Allwinner SoCs have *one* IRQ pin
bank, which contains pins from *multiple* GPIO banks. The A10/A20 for
instance maps the first 22 IRQ pins to Port H0-H21, the remaining 10 IRQ
pins are on port I10-I19. This irq-pin-map is an admittedly
over-engineered attempt to express this is a generic way, trying to
embrace the DT way of mapping things, like we do with the "ranges"
property, for instance.

Recent SoCs just have some GPIO banks which map directly to IRQ pin
banks (on the A64 ports B, G and H map to IRQ bank 0, 1 and 2), so this
is not really needed here. My first version indeed just had a simpler
list to express this.

This series aims to build on top of the existing driver as much as
possible, so some things are not as elegant as they could be.

>> +Optional properties:
>> +- allwinner,port-base: The number of GPIO ports to skip at the beginning.
>> +- allwinner,irq-bank-base: The number of IRQ banks to skip at the beginning.
> 
> I don't understand this. It looks hacky. Can you elaborate why this
> is needed?

It is indeed hacky, and just maps the irq_bank_base member of struct
sunxi_pinctrl_desc into the DT. My understanding is that the A33 skips
the first interrupt bank in the register map, for whatever reason. Might
just be an implementation oddity.
I am just wondering if this could be expressed with the irq-pin-map
above. Or if it's more or less an A33 bug, we could derive this from the
compatible string.

>> +- allwinner,irq-read-needs-mux: Specifies that reading the line level of
>> +  a pin configured as an IRQ pin is not possible. A driver needs to switch
>> +  to the GPIO-in function to be able to read the level.
> 
> I guess it is a bool flag?

Right, should mention that.

>> +Required properties for subnodes:
>> +- pinmux: An array of mux values to write into the respective MMIO register
>> +  bits for this pin when selecting the function. If this array has less
>> +  elements than pins, the *last* value will be used for all pins beyond that.
>> +  This allows to use a single element for the (likely) case all pins use the
>> +  same mux value.
> 
> This is a standard bindings so I don't have much against it. But I
> need Maxime's input here, I think we should keep Allwinner consistent
> across SoCs.

I can understand that, and that's why I choose the new binding to just
be an extension of what we have already.

I am happy to have a discussion on that in general - actually this was
one aim of this series. See the other thread.

I might even write some summary on how it works today and why I believe
it should be improved, I just wasn't sure that was actually needed.

Cheers,
Andre.
--
To unsubscribe from this list: send the line "unsubscribe linux-gpio" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Maxime Ripard Nov. 24, 2017, 12:03 p.m. UTC | #5
Hi Linus,

On Fri, Nov 24, 2017 at 11:19:52AM +0100, Linus Walleij wrote:
> On Mon, Nov 13, 2017 at 2:25 AM, Andre Przywara <andre.przywara@arm.com> wrote:
> 
> > So far all the Allwinner pinctrl drivers provided a table in the
> > kernel to describe all the pins and the link between the pinctrl functions
> > names (strings) and their respective mux values (register values).
> >
> > Extend the binding to put those mappings in the DT, so that any SoC can
> > describe its pinctrl and GPIO data fully there instead of relying on
> > tables.
> > This uses a generic compatible name, to be prepended with an SoC
> > specific name in the node.
> >
> > Signed-off-by: Andre Przywara <andre.przywara@arm.com>
> (...)
> 
> I definately want feedback from Maxime before I do anything with
> this patch series.

So I've been opposed to it as well, for the reasons Rob, Thierry and
you pointed out already in that thread

I just wasn't sure what your opinion on it was, so I didn't answer
just so that I could see if I was the only one pushing back.

So I guess we all agree here.

Maxime
Andre Przywara Nov. 24, 2017, 12:04 p.m. UTC | #6
Hi,

(adding linux-sunxi, which I forgot at the initial post).

On 24/11/17 10:52, Thierry Reding wrote:
> On Fri, Nov 24, 2017 at 11:19:52AM +0100, Linus Walleij wrote:
>> On Mon, Nov 13, 2017 at 2:25 AM, Andre Przywara <andre.przywara@arm.com> wrote:
>>
>>> So far all the Allwinner pinctrl drivers provided a table in the
>>> kernel to describe all the pins and the link between the pinctrl functions
>>> names (strings) and their respective mux values (register values).
>>>
>>> Extend the binding to put those mappings in the DT, so that any SoC can
>>> describe its pinctrl and GPIO data fully there instead of relying on
>>> tables.
>>> This uses a generic compatible name, to be prepended with an SoC
>>> specific name in the node.
> 
> This seems backwards to me. I'm not sure if Rob has any hard rules on
> this, but in the past I've seen a lot of drivers stick this kind of data
> into drivers. I personally also prefer that approach because the data is
> completely static and there's no way for any specific board to customize
> it. So the tables are in fact implied completely by the SoC compatible
> string.

But this is just *data*, and I believe it is actually package specific.
We need the DT to describe the relation between devices and pins anyway,
it's just that we use arbitrary strings today instead of the actual
register value. This is what the generic pinmux property fixes.

> Moving all of this data into device tree has a number of disadvantages:
> 
>   * Existing boards already use the static tables in the driver, and the
>     device trees don't contain any data, so you can't get rid of any of
>     the existing tables because it would break ABI.

Yes, my DeLorean is in the garage, so I can't really change this anymore
;-) But that doesn't mean we have to go on with this forever, I think.

>   * Moving the table into the DT doesn't actually solve anything because
>     the driver would have to validate the DT description to make sure it
>     contains valid data. And in order to validate DT content, the driver
>     would need a copy of the table anyway.

I don't get what the driver would need to validate? We rely on DT
information to be correct anyway, otherwise your board just won't work.
If the DT is wrong, you have much bigger problems.

Actually we gain something, because we only commit information that can
actually be tested. Right now we have a lot of information which is
copied from the manual, and nobody knows if pin H24 on the A10 is really
PATA-CS1 or not. Plus we have bugs when creating the table, plus
copy&paste bugs. I found some while grep-ing for patterns - will send
fixes ASAP.

In the moment all the table gives us is a mapping between a *string* and
the respective mux register value (per pin), plus the number of pins in
each bank. This can *easily* be put in the DT and should belong there.

Actually I believe that the current binding is not correct, because it
makes those mux strings a part of the binding, though this is not
documented anywhere. A developer cannot take the binding and write a
working driver or even a DT without looking at the code.
Plus we already changed those names in the past (for instance commit
bc0f566a98c4), basically breaking compatibility.

> I don't think you're going to do yourself any favours by pushing this. I
> also don't see the commit description give any reason why you want to
> move the table into device tree. Do you see any advantages in doing so?

We stop adding tables with SoC specific *data* in the kernel *code*
base. With being boolean Kconfig options, this gets added to every
single-image kernel.

More important: those tables help Linux, but other DT consumers (*BSD,
U-Boot) have to replicate them, which is just wrong, IMHO.

I believe the kernel is a nice collection of really good code for
complicated file systems, high performance network protocols and
sophisticated memory management, among others. It shouldn't be a dumping
ground for arbitrary, very SoC specific information. Cf. LinusT 2011.
DT is out there to fix this, so we should do so.

Cheers,
Andre.
--
To unsubscribe from this list: send the line "unsubscribe linux-gpio" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Thierry Reding Nov. 24, 2017, 1:31 p.m. UTC | #7
On Fri, Nov 24, 2017 at 12:04:12PM +0000, Andre Przywara wrote:
> Hi,
> 
> (adding linux-sunxi, which I forgot at the initial post).
> 
> On 24/11/17 10:52, Thierry Reding wrote:
> > On Fri, Nov 24, 2017 at 11:19:52AM +0100, Linus Walleij wrote:
> >> On Mon, Nov 13, 2017 at 2:25 AM, Andre Przywara <andre.przywara@arm.com> wrote:
> >>
> >>> So far all the Allwinner pinctrl drivers provided a table in the
> >>> kernel to describe all the pins and the link between the pinctrl functions
> >>> names (strings) and their respective mux values (register values).
> >>>
> >>> Extend the binding to put those mappings in the DT, so that any SoC can
> >>> describe its pinctrl and GPIO data fully there instead of relying on
> >>> tables.
> >>> This uses a generic compatible name, to be prepended with an SoC
> >>> specific name in the node.
> > 
> > This seems backwards to me. I'm not sure if Rob has any hard rules on
> > this, but in the past I've seen a lot of drivers stick this kind of data
> > into drivers. I personally also prefer that approach because the data is
> > completely static and there's no way for any specific board to customize
> > it. So the tables are in fact implied completely by the SoC compatible
> > string.
> 
> But this is just *data*, and I believe it is actually package specific.
> We need the DT to describe the relation between devices and pins anyway,
> it's just that we use arbitrary strings today instead of the actual
> register value. This is what the generic pinmux property fixes.

Register values don't belong in a device tree. And it's totally fine to
have data in the kernel, too. We do it all the time.

> > Moving all of this data into device tree has a number of disadvantages:
> > 
> >   * Existing boards already use the static tables in the driver, and the
> >     device trees don't contain any data, so you can't get rid of any of
> >     the existing tables because it would break ABI.
> 
> Yes, my DeLorean is in the garage, so I can't really change this anymore
> ;-) But that doesn't mean we have to go on with this forever, I think.

ABI stability means that, yes, you have to keep maintaining the existing
tables forever, else old DTBs will stop working if you rip out the
static tables that drivers depend on.

> >   * Moving the table into the DT doesn't actually solve anything because
> >     the driver would have to validate the DT description to make sure it
> >     contains valid data. And in order to validate DT content, the driver
> >     would need a copy of the table anyway.
> 
> I don't get what the driver would need to validate? We rely on DT
> information to be correct anyway, otherwise your board just won't work.
> If the DT is wrong, you have much bigger problems.

Given that DT is an ABI you should treat it the same way as other ABIs.
You can't rely on the DT being correct. Rather you have to make sure to
validate it before you hand the content to hardware. If you allow direct
register access to your hardware via DT and don't validate, it becomes
really easy for people to exploit it.

This is not the same as saying we need to be able to fully validate all
aspects of device tree. We can't, because some information simply does
not exist outside of DT. However, I think it's a big mistake to trust a
user to fully know about all intricacies of a pinmux and not make any
mistake when writing the device tree. What if one of the settings causes
the board to go up in flames?

> Actually we gain something, because we only commit information that can
> actually be tested. Right now we have a lot of information which is
> copied from the manual, and nobody knows if pin H24 on the A10 is really
> PATA-CS1 or not. Plus we have bugs when creating the table, plus
> copy&paste bugs. I found some while grep-ing for patterns - will send
> fixes ASAP.

That's a different matter. If you've got bugs in the tables, then go fix
the tables. However the assumption here is that you've done at least a
minimum of testing and your driver didn't cause your board to go up in
flames. When patches were posted, people had the opportunity to review
the tables for correctness. However, if you put all of the flexibility
into DT, you also put all of the risk there. People may just make some
stupid mistake and cause physical damage to their hardware.

> In the moment all the table gives us is a mapping between a *string* and
> the respective mux register value (per pin), plus the number of pins in
> each bank. This can *easily* be put in the DT and should belong there.

Why? This is data that is implied by the compatible string and static
per SoC. There is no way you can change the mapping in DT. What does
need to go into DT is the configuration of the pinmux, that is, what
function is used for each pin on a given board.

> Actually I believe that the current binding is not correct, because it
> makes those mux strings a part of the binding, though this is not
> documented anywhere. A developer cannot take the binding and write a
> working driver or even a DT without looking at the code.
> Plus we already changed those names in the past (for instance commit
> bc0f566a98c4), basically breaking compatibility.

If you haven't documented the strings your binding is not complete.
That's a bug and should be fixed. Also, it is occasionally acceptable to
break compatibility (it's technically only breaking if somebody notices)
and fixing bugs in bindings has in the past been one of the exceptions
where breaking ABI was specifically allowed.

However, the kind of breakage we're talking about here is total. If you
rip out the static tables from your driver, you don't have any data to
replace the missing information and none of the driver will work. This
is different from the driver erroring out trying to configure a pin for
the NAND function because it couldn't match the name.

Also, device tree bindings are not documentation for how to write a
driver. They are not a replacement for hardware documentation. Nobody
should be expected to be able to write an OS driver solely based on a
device tree binding. Device tree bindings are more of a configuration
interface specification for OS drivers.

> > I don't think you're going to do yourself any favours by pushing this. I
> > also don't see the commit description give any reason why you want to
> > move the table into device tree. Do you see any advantages in doing so?
> 
> We stop adding tables with SoC specific *data* in the kernel *code*
> base. With being boolean Kconfig options, this gets added to every
> single-image kernel.

The kernel is full of data:

	$ objdump -h build/arm64/vmlinux
	[...]
	  1 .text         009c99c0  ffff000008081000  ffff000008081000  00011000  2**11
	                  CONTENTS, ALLOC, LOAD, READONLY, CODE
	  2 .rodata       00403bf8  ffff000008a50000  ffff000008a50000  009e0000  2**12
	                  CONTENTS, ALLOC, LOAD, DATA
	[...]

So that's about 40% of the kernel image. Code really is no good without
data to process.

> More important: those tables help Linux, but other DT consumers (*BSD,
> U-Boot) have to replicate them, which is just wrong, IMHO.

Yeah, I've heard this before. To be honest, I think these tables are the
kind of data that you should generate, and once you do that it becomes
extremely cheap to add the data to other DT consumers.

And let's face it: the really difficult part of adding pinmux support is
to write the driver (or subsystem if you don't have one yet). Adding the
data is really the easy part.

> I believe the kernel is a nice collection of really good code for
> complicated file systems, high performance network protocols and
> sophisticated memory management, among others. It shouldn't be a dumping
> ground for arbitrary, very SoC specific information. Cf. LinusT 2011.
> DT is out there to fix this, so we should do so.

Every driver is very SoC specific information. There's never been an
objection to having SoC specific drivers in the kernel. And back at the
time the discussion was as much about the development process and code
structure than it was about board files.

The majority of the improvements over the years have been achieved by
moving drivers out of arch/arm and moving board files to DT. The goal
was never to get rid of all data.

Thierry
Andre Przywara Nov. 24, 2017, 5:19 p.m. UTC | #8
Hi Thierry,

thanks for the reply and having this discussion!

On 24/11/17 13:31, Thierry Reding wrote:
> On Fri, Nov 24, 2017 at 12:04:12PM +0000, Andre Przywara wrote:
>> Hi,
>>
>> (adding linux-sunxi, which I forgot at the initial post).
>>
>> On 24/11/17 10:52, Thierry Reding wrote:
>>> On Fri, Nov 24, 2017 at 11:19:52AM +0100, Linus Walleij wrote:
>>>> On Mon, Nov 13, 2017 at 2:25 AM, Andre Przywara <andre.przywara@arm.com> wrote:
>>>>
>>>>> So far all the Allwinner pinctrl drivers provided a table in the
>>>>> kernel to describe all the pins and the link between the pinctrl functions
>>>>> names (strings) and their respective mux values (register values).
>>>>>
>>>>> Extend the binding to put those mappings in the DT, so that any SoC can
>>>>> describe its pinctrl and GPIO data fully there instead of relying on
>>>>> tables.
>>>>> This uses a generic compatible name, to be prepended with an SoC
>>>>> specific name in the node.
>>>
>>> This seems backwards to me. I'm not sure if Rob has any hard rules on
>>> this, but in the past I've seen a lot of drivers stick this kind of data
>>> into drivers. I personally also prefer that approach because the data is
>>> completely static and there's no way for any specific board to customize
>>> it. So the tables are in fact implied completely by the SoC compatible
>>> string.
>>
>> But this is just *data*, and I believe it is actually package specific.
>> We need the DT to describe the relation between devices and pins anyway,
>> it's just that we use arbitrary strings today instead of the actual
>> register value. This is what the generic pinmux property fixes.
> 
> Register values don't belong in a device tree.

I don't think that's true in a general way. This "pinmux" is already an
accepted property and used for exactly that purpose in other pinctrl
drivers:
$ git grep -l '[^,]pinmux = ' arch/arm{,64}/boot/dts
Plus the fsl,pinmux-ids property, which seems to serve the same purpose.

> And it's totally fine to
> have data in the kernel, too. We do it all the time.

I know, but that does not mean that I need to like it or should avoid
finding better solutions.

>>> Moving all of this data into device tree has a number of disadvantages:
>>>
>>>   * Existing boards already use the static tables in the driver, and the
>>>     device trees don't contain any data, so you can't get rid of any of
>>>     the existing tables because it would break ABI.
>>
>> Yes, my DeLorean is in the garage, so I can't really change this anymore
>> ;-) But that doesn't mean we have to go on with this forever, I think.
> 
> ABI stability means that, yes, you have to keep maintaining the existing
> tables forever, else old DTBs will stop working if you rip out the
> static tables that drivers depend on.

I think you got me wrong, I am totally not arguing ABI stability and its
consequences. That's why this binding is mostly for newer SoCs, but also
designed to stay compatible with the old binding - that's for other DT
users. Of course we need to keep the tables in the kernel.

>>>   * Moving the table into the DT doesn't actually solve anything because
>>>     the driver would have to validate the DT description to make sure it
>>>     contains valid data. And in order to validate DT content, the driver
>>>     would need a copy of the table anyway.
>>
>> I don't get what the driver would need to validate? We rely on DT
>> information to be correct anyway, otherwise your board just won't work.
>> If the DT is wrong, you have much bigger problems.
> 
> Given that DT is an ABI you should treat it the same way as other ABIs.
> You can't rely on the DT being correct.

But it's not a *user* ABI, where unprivileged users can supply input data.
What else can you rely on then if not on the DT?
By definition you can't be able to validate every bit of it. How would
you know that the reg address of that SATA chip is correct and not
actually pointing to the "set-board-on-fire" device?
And what about those regulators, where it gives you the allowed voltage
range?

> Rather you have to make sure to
> validate it before you hand the content to hardware. If you allow direct
> register access to your hardware via DT and don't validate, it becomes
> really easy for people to exploit it.

If you can change the DT, you already have full control over the system.
Ideally the DT comes as part of the firmware, so if you control this,
there are far less complicated ways to burn down the system. And even if
you supply the DT with your kernel, you must have control and could
trigger the set-fire device via /dev/mem or the like.

> This is not the same as saying we need to be able to fully validate all
> aspects of device tree. We can't, because some information simply does
> not exist outside of DT. However, I think it's a big mistake to trust a
> user to fully know about all intricacies of a pinmux and not make any
> mistake when writing the device tree.

When does a *user* write a device tree? What would a clueless Joe
Average expect from doing so? The device tree is written by either the
board/SoC vendor or by some kernel developers. It is not meant to be
changed by the user, apart from carefully crafted overlays, maybe. You
can have the same control by just changing the kernel (binary patching
the image file or re-compiling with
writel(MATCHES, base_addr + SET_FIRE)).

> What if one of the settings causes the board to go up in flames?

Then you better not play with it. But I don't think this is a valid
argument, really. What if gravity reverses tomorrow?
Are there any known issues with writing mux values to pinctrl registers?
I don't think the consequences would be different from putting low or
high to a GPIO, which you can do already from userland.

>> Actually we gain something, because we only commit information that can
>> actually be tested. Right now we have a lot of information which is
>> copied from the manual, and nobody knows if pin H24 on the A10 is really
>> PATA-CS1 or not. Plus we have bugs when creating the table, plus
>> copy&paste bugs. I found some while grep-ing for patterns - will send
>> fixes ASAP.
> 
> That's a different matter. If you've got bugs in the tables, then go fix
> the tables. However the assumption here is that you've done at least a
> minimum of testing and your driver didn't cause your board to go up in
> flames.

Yes, but at the moment we can't test all of the settings we put in the
kernel table. Some pins are for devices for which we don't have drivers
in the kernel (yet), for some we probably never will (JTAG).
From writing this table for the A64 before I know it's tedious and even
with review there are bugs left. If we can decrease this risk, I am all
for it.

> When patches were posted, people had the opportunity to review
> the tables for correctness. However, if you put all of the flexibility
> into DT, you also put all of the risk there. People may just make some
> stupid mistake and cause physical damage to their hardware.

I don't see how a DT is more risky. Conceptually I consider the DT being
part of the firmware, so one trust level above the kernel. I understand
that some people have different experiences with "firmware", but frankly
I believe this discussion is pointless. If you get the DT wrong, your
board won't work. If the system easily allows you to destroy it by means
of software, you might want to fix it in general, for instance by
telling firmware to not allow access to it from the kernel. Or by
designing hardware in a way that you don't need to expose critical
settings to software. That how x86 solves most of it and what makes it
hard to physically kill a rented root server.
Hiding stuff from the DT and putting molly guards in the kernel does not
really solve this problem.

>> In the moment all the table gives us is a mapping between a *string* and
>> the respective mux register value (per pin), plus the number of pins in
>> each bank. This can *easily* be put in the DT and should belong there.
> 
> Why? This is data that is implied by the compatible string and static
> per SoC. There is no way you can change the mapping in DT. What does
> need to go into DT is the configuration of the pinmux, that is, what
> function is used for each pin on a given board.

Exactly, and that does not change on the *board* level, because there we
just refer to the pinctrl subnode phandles, defined in <soc>.dtsi.
And it's just there that I want to add the right pinmux value.

>> Actually I believe that the current binding is not correct, because it
>> makes those mux strings a part of the binding, though this is not
>> documented anywhere. A developer cannot take the binding and write a
>> working driver or even a DT without looking at the code.
>> Plus we already changed those names in the past (for instance commit
>> bc0f566a98c4), basically breaking compatibility.
> 
> If you haven't documented the strings your binding is not complete.
> That's a bug and should be fixed. Also, it is occasionally acceptable to
> break compatibility (it's technically only breaking if somebody notices)
> and fixing bugs in bindings has in the past been one of the exceptions
> where breaking ABI was specifically allowed.
> 
> However, the kind of breakage we're talking about here is total. If you
> rip out the static tables from your driver, you don't have any data to
> replace the missing information and none of the driver will work. This
> is different from the driver erroring out trying to configure a pin for
> the NAND function because it couldn't match the name.

I think this is a misunderstanding. As mentioned above I never proposed
to remove the tables from the kernel. I think I said this explicitly in
several places:
PATCH 0/3:
> Of course we can't remove the existing tables, to keep compatiblity
> with older DTs, but at least we don't need to add more tables in the
> future.
PATCH 1/3:
> +The binding described above can be extended in this manner to be
supported
> +by *both* an existing driver and some generic driver. Existing
drivers will
> +ignore the new properties and revert to their internal table instead.

I totally understand the concept of compatibility, ask Maxime, he hates
me for that ;-)

> Also, device tree bindings are not documentation for how to write a
> driver. They are not a replacement for hardware documentation. Nobody
> should be expected to be able to write an OS driver solely based on a
> device tree binding. Device tree bindings are more of a configuration
> interface specification for OS drivers.

Yes, but together with the hardware docs you should be able to write a
driver. And here you can't, because you are missing the strings. So a
BSD developer has to look at Linux code.
Sure you can go ahead and add those strings to the binding, but I wonder
how complicated it has to get until we just go with the obviously
simplest way and just add this innocent mux value to the DT.

>>> I don't think you're going to do yourself any favours by pushing this. I
>>> also don't see the commit description give any reason why you want to
>>> move the table into device tree. Do you see any advantages in doing so?
>>
>> We stop adding tables with SoC specific *data* in the kernel *code*
>> base. With being boolean Kconfig options, this gets added to every
>> single-image kernel.
> 
> The kernel is full of data:
> 
> 	$ objdump -h build/arm64/vmlinux
> 	[...]
> 	  1 .text         009c99c0  ffff000008081000  ffff000008081000  00011000  2**11
> 	                  CONTENTS, ALLOC, LOAD, READONLY, CODE
> 	  2 .rodata       00403bf8  ffff000008a50000  ffff000008a50000  009e0000  2**12
> 	                  CONTENTS, ALLOC, LOAD, DATA
> 	[...]
> 
> So that's about 40% of the kernel image. Code really is no good without
> data to process.

But how much of this is SoC specific configuration data? How much is it
in x86? Yes, historically we had and have a lot of configuration data in
ARM kernels. But that doesn't mean that we have to continue with this or
even increase the share.

>> More important: those tables help Linux, but other DT consumers (*BSD,
>> U-Boot) have to replicate them, which is just wrong, IMHO.
> 
> Yeah, I've heard this before. To be honest, I think these tables are the
> kind of data that you should generate, and once you do that it becomes
> extremely cheap to add the data to other DT consumers.

I don't get what's the point of duplicating this information everywhere.
We already have places in the DT to put this information:
	function = "uart1";
So we add "pinmux = <2>" *once* to *the* DT, and everyone gets this for
free. If U-Boot wants to enable MMC0, it just follows the phandle from
pinctrl-0 and writes the value(s) from "pinmux" to the registers derived
from the member of the "pins" string list. No SoC knowledge required.

> And let's face it: the really difficult part of adding pinmux support is
> to write the driver (or subsystem if you don't have one yet). Adding the
> data is really the easy part.

I know, I did this before. But currently you have to write both the DT
part *and* the kernel table. And check patch 3/3, that's what the table
gets reduced to. So you avoid writing 601 lines, instead add 23 lines to
the DT.

>> I believe the kernel is a nice collection of really good code for
>> complicated file systems, high performance network protocols and
>> sophisticated memory management, among others. It shouldn't be a dumping
>> ground for arbitrary, very SoC specific information. Cf. LinusT 2011.
>> DT is out there to fix this, so we should do so.
> 
> Every driver is very SoC specific information. There's never been an
> objection to having SoC specific drivers in the kernel. And back at the
> time the discussion was as much about the development process and code
> structure than it was about board files.
> 
> The majority of the improvements over the years have been achieved by
> moving drivers out of arch/arm and moving board files to DT. The goal
> was never to get rid of all data.

Sure, not all data. But if we have the relatively easy opportunity to
avoid further addition of data, we should do it, I believe.
This significantly reduces the amount of kernel code we need to add to
support new SoCs.

Cheers,
Andre.
--
To unsubscribe from this list: send the line "unsubscribe linux-gpio" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Maxime Ripard Nov. 27, 2017, 8:34 a.m. UTC | #9
On Fri, Nov 24, 2017 at 05:19:24PM +0000, Andre Przywara wrote:
> > This is not the same as saying we need to be able to fully validate all
> > aspects of device tree. We can't, because some information simply does
> > not exist outside of DT. However, I think it's a big mistake to trust a
> > user to fully know about all intricacies of a pinmux and not make any
> > mistake when writing the device tree.
> 
> When does a *user* write a device tree? What would a clueless Joe
> Average expect from doing so? The device tree is written by either the
> board/SoC vendor or by some kernel developers. It is not meant to be
> changed by the user, apart from carefully crafted overlays, maybe. You
> can have the same control by just changing the kernel (binary patching
> the image file or re-compiling with
> writel(MATCHES, base_addr + SET_FIRE)).

I guess the expectation should be that it's a Joe Average user in the
Allwinner case at least. It's far from the exception that someone that
never got any kernel (or electronics) experience before jumps in,
creates a DT for the shiny new board they just received and then
submits it.

I guess it's more the case in the Allwinner case than for any other
SoCs I've worked on at least, probably because of its widespread use
in the low-end consumer market and their reputation amongst hackers,
but still, this is basically our default.

> > What if one of the settings causes the board to go up in flames?
> 
> Then you better not play with it. But I don't think this is a valid
> argument, really. What if gravity reverses tomorrow?
> Are there any known issues with writing mux values to pinctrl registers?
> I don't think the consequences would be different from putting low or
> high to a GPIO, which you can do already from userland.

I guess the difference would be that's it's active in your example,
while the pinmux will be set even if a user doesn't do anything. And I
can testify that you can very well permanently fry a board passively
using pinctrl :)

> > And let's face it: the really difficult part of adding pinmux support is
> > to write the driver (or subsystem if you don't have one yet). Adding the
> > data is really the easy part.
> 
> I know, I did this before. But currently you have to write both the DT
> part *and* the kernel table. And check patch 3/3, that's what the table
> gets reduced to. So you avoid writing 601 lines, instead add 23 lines to
> the DT.

And I'll just add here that if the data size is of concern, as it can
be in a bootloader, you can very well have partial tables. There's
plenty of devices that will be of no use in a bootloader.

Maxime
Linus Walleij Dec. 1, 2017, 9:38 a.m. UTC | #10
On Fri, Nov 24, 2017 at 6:19 PM, Andre Przywara <andre.przywara@arm.com> wrote:
> On 24/11/17 13:31, Thierry Reding wrote:

>> Register values don't belong in a device tree.
>
> I don't think that's true in a general way. This "pinmux" is already an
> accepted property and used for exactly that purpose in other pinctrl
> drivers:
> $ git grep -l '[^,]pinmux = ' arch/arm{,64}/boot/dts
> Plus the fsl,pinmux-ids property, which seems to serve the same purpose.

There are several examples of register values (and register
numbers even!) being encoded in the kernel.

What we need to ask is whether that is good in the general case
or bad. I don't even think that has a clear answer, it's a grey area.

So we need to avoid "arguments from consistency" which reads
something like "you allowed this thing A so now you must allow
this thing B which is similar". It is not a helpful approach to the
problem.

Some drivers encode a bunch of data into the device tree,
pinctrl-single is the most extreme. This conflict between in-DT
and in-driver data storage has been there since pinctrl was created
and was the result of a compromise between OMAPs needs
and everyone else, especially Tegra.

The opinions on this - and it is really opinions, not facts - differ
between people and over time.

Resolving the conflicts is more about classical diplomacy than
science unfortunately. I used to think the christian trinity was
amusing and inconsistent, but nowadays I understand exactly how
the people who came up with the Nicean creed were reasoning.

What is paramount for me as subsystem maintainer is the fact
that this driver has an active maintainer. And maintainers
is what makes things manageable for me. It would be much easier
for you to have your way if you were submitting an entirely
new driver. Like this pinmux property, it was submitted by the
mediatek people because it fits their usecase/hardware especially
well.

Yours,
Linus Walleij
--
To unsubscribe from this list: send the line "unsubscribe linux-gpio" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Linus Walleij Dec. 1, 2017, 9:56 a.m. UTC | #11
On Fri, Nov 24, 2017 at 6:19 PM, Andre Przywara <andre.przywara@arm.com> wrote:

> Conceptually I consider the DT being
> part of the firmware,

As it is a subset of open firmware it is obviously firmware.

> so one trust level above the kernel.

We are several kernel developers who don't trust firmware one
bit. Several disasters in ACPI has made me ever more convinced
that firmware should be trusted less than kernel code.

But this is all very academic.

>> Also, device tree bindings are not documentation for how to write a
>> driver. They are not a replacement for hardware documentation. Nobody
>> should be expected to be able to write an OS driver solely based on a
>> device tree binding. Device tree bindings are more of a configuration
>> interface specification for OS drivers.
>
> Yes, but together with the hardware docs you should be able to write a
> driver. And here you can't, because you are missing the strings. So a
> BSD developer has to look at Linux code.

This is a fair point. It appears in several drivers.

BSD or even Windows (would they use DT) would have to sit in the
back seat just like Linux has been doing for years when it comes
to the hopeless Windowsisms in the x86 BIOSes. I suspect some
Windows on ARM is already experiencing this, but in the ACPI world,
where, incidentally, the servers were being deployed for Linux first
and Windows had to follow their example. I bet they have been
swearing a lot in Redmond about that.

In general it's one of these areas where we can not be utopian about the
hardware descriptions, just fail gracefully in different ways.

I usually try to keep the IETF motto "rough consensus and running
code" in mind. I don't know if it helps in this discussion though.

>> So that's about 40% of the kernel image. Code really is no good without
>> data to process.
>
> But how much of this is SoC specific configuration data? How much is it
> in x86? Yes, historically we had and have a lot of configuration data in
> ARM kernels. But that doesn't mean that we have to continue with this or
> even increase the share.

What people have been doing is trying to have better Kconfig setups
and compile it out by doing kernel modules. It is a bit hopeless with
pin controllers: almost all of them have to be built in. And if they come
with a lot of data, yeah there you have a real good point.

It would be sad if the ARMv7 multiboot or Aarch64 kernel just grows
so that we can't use it but have to go back to shipping board-specific
kernels with a huge bunch of stuff compiled out.

I was hoping Moore's law would save us here :/

An option that has been discussed is better used of  __initdata
and similar tags, especially with built-in drivers. Sadly, this is
hurt by another snag: the compiler or linker file or whatever it is,
is preventing us from discarding any strings from the kernel.
And pin controllers tend to stack up a lot of these.

This is really sucky and something we should solve in general.
I'm not smart enough to tackle any of these problems myself, just
to see them and "Oh that's bad. Very bad."

>> The majority of the improvements over the years have been achieved by
>> moving drivers out of arch/arm and moving board files to DT. The goal
>> was never to get rid of all data.
>
> Sure, not all data. But if we have the relatively easy opportunity to
> avoid further addition of data, we should do it, I believe.
> This significantly reduces the amount of kernel code we need to add to
> support new SoCs.

This is the core of your argument as I perceive it: get rid of data
from the kernel, because it is growing wild. It is a valid cause. Just
has to be weighed with other stuff, like maintainability, debuggability,
maintainers viewpoint. ...

Yours,
Linus Walleij
--
To unsubscribe from this list: send the line "unsubscribe linux-gpio" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Andre Przywara Dec. 6, 2017, 12:55 a.m. UTC | #12
Hi Linus,

thanks for the reply!

On 01/12/17 09:56, Linus Walleij wrote:
> On Fri, Nov 24, 2017 at 6:19 PM, Andre Przywara <andre.przywara@arm.com> wrote:
> 
>> Conceptually I consider the DT being
>> part of the firmware,
> 
> As it is a subset of open firmware it is obviously firmware.
> 
>> so one trust level above the kernel.
> 
> We are several kernel developers who don't trust firmware one
> bit. Several disasters in ACPI has made me ever more convinced
> that firmware should be trusted less than kernel code.

I know what you mean, check commit acd316248205 ;-)

But in the Allwinner case all the firmware is open source, and even
controlled by the community (ATF & U-Boot). This is even more true for
the DT. Allwinner came up with their own DT, but since it uses
completely non-standard bindings, we don't use it at all.

So I don't consider firmware this dark, evil and unhackable blob that
many people see in it. Instead it is a good opportunity to separate very
tedious machine-specific parts from the kernel (think of PSCI).

> But this is all very academic.

I agree!

>>> Also, device tree bindings are not documentation for how to write a
>>> driver. They are not a replacement for hardware documentation. Nobody
>>> should be expected to be able to write an OS driver solely based on a
>>> device tree binding. Device tree bindings are more of a configuration
>>> interface specification for OS drivers.
>>
>> Yes, but together with the hardware docs you should be able to write a
>> driver. And here you can't, because you are missing the strings. So a
>> BSD developer has to look at Linux code.
> 
> This is a fair point. It appears in several drivers.
> 
> BSD or even Windows (would they use DT) would have to sit in the
> back seat just like Linux has been doing for years when it comes
> to the hopeless Windowsisms in the x86 BIOSes. I suspect some
> Windows on ARM is already experiencing this, but in the ACPI world,
> where, incidentally, the servers were being deployed for Linux first
> and Windows had to follow their example. I bet they have been
> swearing a lot in Redmond about that.

On the other hand a lot of the ACPI tables have been either taken from
x86 or designed also with Windows in mind. And frankly, my sympathy for
MS is quite limited in this respect ;-)

> In general it's one of these areas where we can not be utopian about the
> hardware descriptions, just fail gracefully in different ways.
> 
> I usually try to keep the IETF motto "rough consensus and running
> code" in mind. I don't know if it helps in this discussion though.
> 
>>> So that's about 40% of the kernel image. Code really is no good without
>>> data to process.
>>
>> But how much of this is SoC specific configuration data? How much is it
>> in x86? Yes, historically we had and have a lot of configuration data in
>> ARM kernels. But that doesn't mean that we have to continue with this or
>> even increase the share.
> 
> What people have been doing is trying to have better Kconfig setups
> and compile it out by doing kernel modules. It is a bit hopeless with
> pin controllers: almost all of them have to be built in. And if they come
> with a lot of data, yeah there you have a real good point.
> 
> It would be sad if the ARMv7 multiboot or Aarch64 kernel just grows
> so that we can't use it but have to go back to shipping board-specific
> kernels with a huge bunch of stuff compiled out.
> 
> I was hoping Moore's law would save us here :/
> 
> An option that has been discussed is better used of  __initdata
> and similar tags, especially with built-in drivers. Sadly, this is
> hurt by another snag: the compiler or linker file or whatever it is,
> is preventing us from discarding any strings from the kernel.
> And pin controllers tend to stack up a lot of these.
> 
> This is really sucky and something we should solve in general.
> I'm not smart enough to tackle any of these problems myself, just
> to see them and "Oh that's bad. Very bad."

I am sure one can find clever hac^Wsolutions for this problem, but I was
wondering if a new approach - like putting the per machine data actually
in DT - isn't the smarter way.
Hence my suggestion with this driver: we *need* the DT anyway to assign
pins to devices, so why not just add the few bytes *there*, which allows
us to have a more or less "data-less" DT driver?

From what I learned the pinctrl subsystem seems to predates the ARM DT
endeavor, so many design decisions probably didn't consider DT as a
possible solution in the first way. And this is fine, because this is
how it was back then. But it doesn't mean it has to stay this way. And I
carefully thought of solving this problem without alienating existing
users and developers - by keeping the driver and staying compatible with
the existing binding and the DTs.

>>> The majority of the improvements over the years have been achieved by
>>> moving drivers out of arch/arm and moving board files to DT. The goal
>>> was never to get rid of all data.
>>
>> Sure, not all data. But if we have the relatively easy opportunity to
>> avoid further addition of data, we should do it, I believe.
>> This significantly reduces the amount of kernel code we need to add to
>> support new SoCs.
> 
> This is the core of your argument as I perceive it: get rid of data
> from the kernel, because it is growing wild.

Yes, this, but also to avoid replicating data in other DT consumers. I
very much like the idea of the DT describing the hardware, but I am a
bit afraid we loose many good opportunities by treating the DT more like
a "Linux config file" or an external Linux board file.
So I wanted to propose a way where we simplify DT usage in other
systems, while still keeping the Linux driver intact.

> It is a valid cause. Just
> has to be weighed with other stuff, like maintainability, debuggability,
> maintainers viewpoint. ...

So to keep Maxime happy I actually designed this "driver" more like a
shim: to generate the table the current driver expects from the DT, and
actually not touching the existing driver at all.
So maintainability should actually be less of a concern: the driver will
just work with whatever one throws at it from the DT side, without
requiring frequent changes or additions.
In the moment we still need to write, review and merge *data* files for
each new SoC. And as I mentioned before, Allwinner decided to push for
new, slightly different chips every few months, so there will be more to
come. With at least the pinctrl driver out of the way we have one
problem less to worry about.

Cheers,
Andre.
--
To unsubscribe from this list: send the line "unsubscribe linux-gpio" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Linus Walleij Dec. 12, 2017, 10:52 a.m. UTC | #13
On Wed, Dec 6, 2017 at 1:55 AM, André Przywara <andre.przywara@arm.com> wrote:
> On 01/12/17 09:56, Linus Walleij wrote:

>> It is a valid cause. Just
>> has to be weighed with other stuff, like maintainability, debuggability,
>> maintainers viewpoint. ...
>
> So to keep Maxime happy I actually designed this "driver" more like a
> shim: to generate the table the current driver expects from the DT, and
> actually not touching the existing driver at all.
> So maintainability should actually be less of a concern: the driver will
> just work with whatever one throws at it from the DT side, without
> requiring frequent changes or additions.
> In the moment we still need to write, review and merge *data* files for
> each new SoC. And as I mentioned before, Allwinner decided to push for
> new, slightly different chips every few months, so there will be more to
> come. With at least the pinctrl driver out of the way we have one
> problem less to worry about.

I think you need mainly to convince Maxime that this is something that
he wants to maintain, going forward.

I am as subsystem maintainer pretty pleased as long as standard
properties etc are used to encode the data into the devicetree, and
DT maintrainers are not actively vetoing what you do.

If it leads to a conflict between Allwinner maintainers it is not worth the
effort for reasons that are social rather than technical. To me it is a very
nice but as with all volunteer communities also very vulnerable
endavour.

Please make sure not to push your point so hard that it hurts your
our your colleagues feelings.

I know people are passionate about their ideas, which is usally good
but also scare me sometimes because they sometimes become so
passionate that it makes them bad team players.

Yours,
Linus Walleij
--
To unsubscribe from this list: send the line "unsubscribe linux-gpio" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
diff mbox series

Patch

diff --git a/Documentation/devicetree/bindings/pinctrl/allwinner,sunxi-pinctrl.txt b/Documentation/devicetree/bindings/pinctrl/allwinner,sunxi-pinctrl.txt
index 6f2ec9af0de2..c1ea755229da 100644
--- a/Documentation/devicetree/bindings/pinctrl/allwinner,sunxi-pinctrl.txt
+++ b/Documentation/devicetree/bindings/pinctrl/allwinner,sunxi-pinctrl.txt
@@ -28,6 +28,7 @@  Required properties:
   "allwinner,sun50i-a64-r-pinctrl"
   "allwinner,sun50i-h5-pinctrl"
   "nextthing,gr8-pinctrl"
+  "allwinner,sunxi-pinctrl"	(see below)
 
 - reg: Should contain the register physical address and length for the
   pin controller.
@@ -69,6 +70,63 @@  Optional sub-node properties:
   - bias-pull-down
   - drive-strength
 
+** Generic pinctrl binding
+The above binding requires knowledge of the actual mux setting values for
+each supported SoC in the code parsing the DT (for instance the kernel).
+The generic binding puts this information in the DT. It uses the
+"allwinner,sunxi-pinctrl" compatible, in addition to some SoC specific string.
+It extends the above described binding as follows:
+Required properties:
+- allwinner,gpio-pins: An array of 32-bit numbers to denote the number of
+  implemented pins per pin controller port. Non-implemented ports can specify
+  0 here. There will be as many ports as this array has elements.
+- allwinner,irq-pin-map: Contains a number of IRQ port maps, describing the
+  relationship between interrupt banks and GPIO pins. Each map has six 32-bit
+  members:
+  <[IRQ port] [1st IRQ pin] [GPIO port] [1st GPIO pin] [mux value] [length]>
+  This maps the first [length] IRQ pins starting with [IRQ port]:[1st IRQ pin]
+  to [GPIO port]:[1st GPIO pin], all using [mux value] to select the IRQ
+  functionality.
+
+Optional properties:
+- allwinner,port-base: The number of GPIO ports to skip at the beginning.
+- allwinner,irq-bank-base: The number of IRQ banks to skip at the beginning.
+- allwinner,irq-read-needs-mux: Specifies that reading the line level of
+  a pin configured as an IRQ pin is not possible. A driver needs to switch
+  to the GPIO-in function to be able to read the level.
+
+Required properties for subnodes:
+- pinmux: An array of mux values to write into the respective MMIO register
+  bits for this pin when selecting the function. If this array has less
+  elements than pins, the *last* value will be used for all pins beyond that.
+  This allows to use a single element for the (likely) case all pins use the
+  same mux value.
+
+The binding described above can be extended in this manner to be supported
+by *both* an existing driver and some generic driver. Existing drivers will
+ignore the new properties and revert to their internal table instead.
+
+Example:
+  pinctrl@1c20800 {
+	compatible = "allwinner,sun50i-a64-pinctrl",
+		     "allwinner,sunxi-pinctrl";
+	reg = <0x01c20800 0x400>;
+	clocks = <&ccu 58>, <&hosc>, <&losc>;
+	/* No PortA, PB0-PB9, PC0-PC16, PD0-PD24, ... */
+	allwinner,gpio-pins = <0 10 17 25 18 7 14 12>;
+	/* banks B, G and H can trigger interrupts, using mux value 6 */
+	allwinner,irq-pin-map= <0 0 1 0 6 10>,
+			       <1 0 6 0 6 14>,
+			       <2 0 7 0 6 12>;
+	i2c1_pins: i2c1_pins {
+		pins = "PH2", "PH3";
+		function = "i2c1";
+		/* Both pins use a mux value of 2 to select this function. */
+		pinmux = <2>;
+	};
+	...
+  };
+
 *** Deprecated pin configuration and multiplexing binding
 
 Required subnode-properties: