dt-bindings: add a jsonschema binding example
Rob Herring
maintainerRFC PATCH 1/1 dt-bindings: add a jsonschema binding example
The current DT binding documentation format of freeform text is painful to write, review, validate and maintain.
This is just an example of what a binding in the schema format looks like. It's using jsonschema vocabulary in a YAML encoded document. Using jsonschema gives us access to existing tooling. A YAML encoding gives us something easy to edit.
This example is just the tip of the iceberg, but it the part most developers writing bindings will interact with. Backing all this up are meta-schema (to validate the binding schemas), some DT core schema, YAML encoded DT output with dtc, and a small number of python scripts to run validation. The gory details including how to run end-to-end validation can be found here:
https://www.spinics.net/lists/devicetree-spec/msg00649.html
---
Cc list,
You all review and/or write lots of binding documents. I'd like some feedback on the format.
Thanks,
Rob
.../devicetree/bindings/example-schema.yaml | 149 +++++++++++++++++++++ 1 file changed, 149 insertions(+) create mode 100644 Documentation/devicetree/bindings/example-schema.yaml
Documentation/devicetree/bindings/example-schema.yaml new file +149 -0
@@ -0,0 +1,149 @@ +# SPDX-License-Identifier: BSD-2-Clause +# Copyright 2018 Linaro Ltd. +%YAML 1.2 +--- +# All the top-level keys are standard json-schema keywords except for +# 'maintainers' and 'select' + +# $id is a unique idenifier based on the filename +$id: "http://devicetree.org/schemas/example-schema.yaml#" +$schema: "http://devicetree.org/meta-schemas/core.yaml#" + +# Only 1 version supported for now +version: 1 + +title: An example schema annotated with jsonschema details + +maintainers: + - Rob Herring <[email protected]> + +description: | + A more detailed multi-line description of the binding. + + Details about the hardware device and any links to datasheets can go here. + + The end of the description is marked by indentation less than the first line + in the description. + +select: false + # 'select' is a schema applied to a DT node to determine if this binding + # schema should be applied to the node. It is optional and by default the + # possible compatible strings are extracted and used to match. + +properties: + # A dictionary of DT properties for this binding schema + compatible: + # More complicated schema can use oneOf (XOR), anyOf (OR), or allOf (AND) + # to handle different conditions. + # In this case, it's needed to handle a variable number of values as there + # isn't another way to express a constraint of the last string value. + # The boolean schema must be a list of schemas. + oneOf: + - items: + # items is a list of possible values for the property. The number of + # values is determined by the number of elements in the list. + # Order in lists is significant, order in dicts is not + # Must be one of the 1st enums followed by the 2nd enum + # + # Each element in items should be 'enum' or 'const' + - enum: + - vendor,soc4-ip + - vendor,soc3-ip + - vendor,soc2-ip + - enum: + - vendor,soc1-ip + # additionalItems being false is implied + # minItems/maxItems equal to 2 is implied + - items: + # 'const' is just a special case of an enum with a single possible value + - const: vendor,soc1-ip + + reg: + # The description of each element defines the order and implicitly defines + # the number of reg entries + items: + - description: core registers + - description: aux registers + # minItems/maxItems equal to 2 is implied + + reg-names: + # The core schema enforces this is a string array + items: + - const: core + - const: aux + + clocks: + # Only a single entry, so just need to set the max number of items. + maxItems: 1 + + clock-names: + items: + - const: bus + + interrupts: + # Either 1 or 2 interrupts can be present + minItems: 1 + maxItems: 2 + items: + - description: tx or combined interrupt + - description: rx interrupt + + description: | + A variable number of interrupts warrants a description of what conditions + affect the number of interrupts. Otherwise, descriptions on standard + properties are not necessary. + + interrupt-names: + # minItems must be specified here because the default would be 2 + minItems: 1 + items: + - const: "tx irq" + - const: "rx irq" + + # Property names starting with '#' must be quoted + '#interrupt-cells': + # A simple case where the value must always be '2'. + # The core schema handles that this must be a single integer. + const: 2 + + interrupt-controller: {} + # The core checks this is a boolean, so just have to list it here to be + # valid for this binding. + + clock-frequency: + # The type is set in the core schema. Per device schema only need to set + # constraints on the possible values. + minimum: 100 + maximum: 400000 + # The value that should be used if the property is not present + default: 200 + + foo-gpios: + maxItems: 1 + description: A connection of the 'foo' gpio line. + + vendor,int-property: + description: Vendor specific properties must have a description + type: integer # A type is also required + enum: [2, 4, 6, 8, 10] + + vendor,bool-property: + description: Vendor specific properties must have a description + type: boolean + +required: + - compatible + - reg + - interrupts + - interrupt-controller + +examples: + - | + /{ + compatible = "vendor,soc4-ip", "vendor,soc1-ip"; + reg = <0x1000 0x80>, + <0x3000 0x80>; + reg-names = "core", "aux"; + interrupts = <10>; + interrupt-controller; + };
--
2.14.1
Quoting Rob Herring (2018-04-18 15:29:05)
Quoted 27 lines
Documentation/devicetree/bindings/example-schema.yaml new file +21
-0@@ -0,0 +1,149 @@ +# SPDX-License-Identifier: BSD-2-Clause +# Copyright 2018 Linaro Ltd. +%YAML 1.2 +--- +# All the top-level keys are standard json-schema keywords except for +# 'maintainers' and 'select' + +# $id is a unique idenifier based on the filename +$id: "http://devicetree.org/schemas/example-schema.yaml#" +$schema: "http://devicetree.org/meta-schemas/core.yaml#" + +# Only 1 version supported for now +version: 1 + +title: An example schema annotated with jsonschema details + +maintainers: + - Rob Herring <[email protected]> + +description: | + A more detailed multi-line description of the binding.
Documentation/devicetree/bindings/example-schema.yaml line 31
Quoted 10 lines
Documentation/devicetree/bindings/example-schema.yaml new file +10
-0+ + Details about the hardware device and any links to datasheets can go here. + + The end of the description is marked by indentation less than the first line + in the description. + +select: false + # 'select' is a schema applied to a DT node to determine if this binding + # schema should be applied to the node. It is optional and by default the + # possible compatible strings are extracted and used to match.
Can we get a concrete example here?
Quoted 2 lines
Documentation/devicetree/bindings/example-schema.yaml new file +2
-0+ +properties:
[...]
Documentation/devicetree/bindings/example-schema.yaml line 91
Quoted 10 lines
Documentation/devicetree/bindings/example-schema.yaml new file +10
-0+ + interrupts: + # Either 1 or 2 interrupts can be present + minItems: 1 + maxItems: 2 + items: + - description: tx or combined interrupt + - description: rx interrupt + + description: |
The '|' is needed to make yaml happy?
Quoted 8 lines
Documentation/devicetree/bindings/example-schema.yaml new file +8
-0+ A variable number of interrupts warrants a description of what conditions + affect the number of interrupts. Otherwise, descriptions on standard + properties are not necessary. + + interrupt-names: + # minItems must be specified here because the default would be 2 + minItems: 1 + items:
Documentation/devicetree/bindings/example-schema.yaml line 109
Quoted 10 lines
Documentation/devicetree/bindings/example-schema.yaml new file +10
-0+ - const: "tx irq" + - const: "rx irq" + + # Property names starting with '#' must be quoted + '#interrupt-cells': + # A simple case where the value must always be '2'. + # The core schema handles that this must be a single integer. + const: 2 + + interrupt-controller: {}
Does '{}' mean nothing to see here?
Documentation/devicetree/bindings/example-schema.yaml line 120
Quoted 11 lines
Documentation/devicetree/bindings/example-schema.yaml new file +11
-0+ # The core checks this is a boolean, so just have to list it here to be + # valid for this binding. + + clock-frequency: + # The type is set in the core schema. Per device schema only need to set + # constraints on the possible values. + minimum: 100 + maximum: 400000 + # The value that should be used if the property is not present + default: 200 +
The 'default' field is neat. I look forward to the compiler using the schema to insert defaults into the dtb if the properties aren't present in the input file.
Quoted 8 lines
Documentation/devicetree/bindings/example-schema.yaml new file +8
-0+ foo-gpios: + maxItems: 1 + description: A connection of the 'foo' gpio line. + + vendor,int-property: + description: Vendor specific properties must have a description + type: integer # A type is also required + enum: [2, 4, 6, 8, 10]
Documentation/devicetree/bindings/example-schema.yaml line 138
Quoted 10 lines
Documentation/devicetree/bindings/example-schema.yaml new file +10
-0+ + vendor,bool-property: + description: Vendor specific properties must have a description + type: boolean + +required: + - compatible + - reg + - interrupts + - interrupt-controller
Can the required or optional parts go under each property instead of having a different section? Or does that make the schema parser difficult to implement? It may also make sense to negate this and specify only the optional properties, or to require both optional and required lists to make things more explicit at the cost of some verbosity.
Documentation/devicetree/bindings/example-schema.yaml line 142
Quoted 4 lines
Documentation/devicetree/bindings/example-schema.yaml new file +4
-0+ +examples: + - | + /{
Is the first slash required here?
Quoted 7 lines
Documentation/devicetree/bindings/example-schema.yaml new file +7
-0+ compatible = "vendor,soc4-ip", "vendor,soc1-ip"; + reg = <0x1000 0x80>, + <0x3000 0x80>; + reg-names = "core", "aux"; + interrupts = <10>; + interrupt-controller; + };
Rob Herring
maintainerQuoted 32 lines · Stephen Boyd
Quoting Rob Herring (2018-04-18 15:29:05)
Quoted 31 lines
Documentation/devicetree/bindings/example-schema.yaml new file +25
-0@@ -0,0 +1,149 @@ +# SPDX-License-Identifier: BSD-2-Clause +# Copyright 2018 Linaro Ltd. +%YAML 1.2 +--- +# All the top-level keys are standard json-schema keywords except for +# 'maintainers' and 'select' + +# $id is a unique idenifier based on the filename +$id: "http://devicetree.org/schemas/example-schema.yaml#" +$schema: "http://devicetree.org/meta-schemas/core.yaml#" + +# Only 1 version supported for now +version: 1 + +title: An example schema annotated with jsonschema details + +maintainers: + - Rob Herring <[email protected]> + +description: | + A more detailed multi-line description of the binding. + + Details about the hardware device and any links to datasheets can go here. + + The end of the description is marked by indentation less than the first line
Quoted 8 lines
Documentation/devicetree/bindings/example-schema.yaml line 31
Quoted 6 lines
Documentation/devicetree/bindings/example-schema.yaml new file +6
-0+ in the description. + +select: false + # 'select' is a schema applied to a DT node to determine if this binding + # schema should be applied to the node. It is optional and by default the + # possible compatible strings are extracted and used to match.Can we get a concrete example here?
select: true
:) Which is apply to every node.
A better one is from the memory node schema ('$nodename' gets added :
select:
required: ["$nodename"]
properties:
$nodename:
oneOf:
- pattern: "^memory@[0-9a-f]*"
- const: "memory" # 'memory' only allowed for selecting
I expect the vast majority of device bindings will not use select at all and rely on compatible string matching.
Quoted 15 lines
Quoted 2 lines
Documentation/devicetree/bindings/example-schema.yaml new file +2
-0+ +properties:[...]
Documentation/devicetree/bindings/example-schema.yaml line 91
Quoted 10 lines
Documentation/devicetree/bindings/example-schema.yaml new file +10
-0+ + interrupts: + # Either 1 or 2 interrupts can be present + minItems: 1 + maxItems: 2 + items: + - description: tx or combined interrupt + - description: rx interrupt + + description: |The '|' is needed to make yaml happy?
Yes, this is simply how you do literal text blocks in yaml.
We don't really need for this one really, but for the top-level 'description' we do. The long term intent is 'description' would be written in sphinx/rst and can be extracted into the DT spec (for common bindings). Grant has experimented with that some.
Quoted 12 lines
Quoted 12 lines
Documentation/devicetree/bindings/example-schema.yaml new file +12
-0+ A variable number of interrupts warrants a description of what conditions + affect the number of interrupts. Otherwise, descriptions on standard + properties are not necessary. + + interrupt-names: + # minItems must be specified here because the default would be 2 + minItems: 1 + items: + - const: "tx irq" + - const: "rx irq" + + # Property names starting with '#' must be quoted
Quoted 8 lines
Documentation/devicetree/bindings/example-schema.yaml line 109
Quoted 6 lines
Documentation/devicetree/bindings/example-schema.yaml new file +6
-0+ '#interrupt-cells': + # A simple case where the value must always be '2'. + # The core schema handles that this must be a single integer. + const: 2 + + interrupt-controller: {}Does '{}' mean nothing to see here?
Yes. It's just an empty schema that's always valid.
Quoted 7 lines
Quoted 7 lines
Documentation/devicetree/bindings/example-schema.yaml new file +7
-0+ # The core checks this is a boolean, so just have to list it here to be + # valid for this binding. + + clock-frequency: + # The type is set in the core schema. Per device schema only need to set + # constraints on the possible values. + minimum: 100
Quoted 8 lines
Documentation/devicetree/bindings/example-schema.yaml line 120
Quoted 4 lines
Documentation/devicetree/bindings/example-schema.yaml new file +4
-0+ maximum: 400000 + # The value that should be used if the property is not present + default: 200 +The 'default' field is neat. I look forward to the compiler using the schema to insert defaults into the dtb if the properties aren't present in the input file.
That wasn't really my intention, but it's what the OS should use if property is not present. But at least for required properties, we could certainly do as you suggest.
Quoted 13 lines
Quoted 13 lines
Documentation/devicetree/bindings/example-schema.yaml new file +13
-0+ foo-gpios: + maxItems: 1 + description: A connection of the 'foo' gpio line. + + vendor,int-property: + description: Vendor specific properties must have a description + type: integer # A type is also required + enum: [2, 4, 6, 8, 10] + + vendor,bool-property: + description: Vendor specific properties must have a description + type: boolean +
Quoted 8 lines
Documentation/devicetree/bindings/example-schema.yaml line 138
Quoted 5 lines
Documentation/devicetree/bindings/example-schema.yaml new file +5
-0+required: + - compatible + - reg + - interrupts + - interrupt-controllerCan the required or optional parts go under each property instead of having a different section?
No, because then it is not json-schema language.
Quoted 2 lines
Or does that make the schema parser
difficult to implement?
Yes, because then we have to implement a schema parser.
Quoted 11 lines
It may also make sense to negate this and
specify only the optional properties, or to require both optional and required lists to make things more explicit at the cost of some verbosity.Documentation/devicetree/bindings/example-schema.yaml line 142
Quoted 4 lines
Documentation/devicetree/bindings/example-schema.yaml new file +4
-0+ +examples: + - | + /{Is the first slash required here?
No, just leftover from being the root node in the example.
Thanks for taking a look.
Quoted 7 lines
Quoted 7 lines
Documentation/devicetree/bindings/example-schema.yaml new file +7
-0+ compatible = "vendor,soc4-ip", "vendor,soc1-ip"; + reg = <0x1000 0x80>, + <0x3000 0x80>; + reg-names = "core", "aux"; + interrupts = <10>; + interrupt-controller; + };
Quoted 122 lines · Rob Herring
Quoted 32 lines · Stephen Boyd
Quoting Rob Herring (2018-04-18 15:29:05)
Quoted 31 lines
Documentation/devicetree/bindings/example-schema.yaml new file +25
-0@@ -0,0 +1,149 @@ +# SPDX-License-Identifier: BSD-2-Clause +# Copyright 2018 Linaro Ltd. +%YAML 1.2 +--- +# All the top-level keys are standard json-schema keywords except for +# 'maintainers' and 'select' + +# $id is a unique idenifier based on the filename +$id: "http://devicetree.org/schemas/example-schema.yaml#" +$schema: "http://devicetree.org/meta-schemas/core.yaml#" + +# Only 1 version supported for now +version: 1 + +title: An example schema annotated with jsonschema details + +maintainers: + - Rob Herring <[email protected]> + +description: | + A more detailed multi-line description of the binding. + + Details about the hardware device and any links to datasheets can go here. + + The end of the description is marked by indentation less than the first lineQuoted 8 lines
Documentation/devicetree/bindings/example-schema.yaml line 31
Quoted 6 lines
Documentation/devicetree/bindings/example-schema.yaml new file +6
-0+ in the description. + +select: false + # 'select' is a schema applied to a DT node to determine if this binding + # schema should be applied to the node. It is optional and by default the + # possible compatible strings are extracted and used to match.Can we get a concrete example here?
select: true
:) Which is apply to every node.
A better one is from the memory node schema ('$nodename' gets added :
select:
required: ["$nodename"]
properties:
$nodename:
oneOf:
- pattern: "^memory@[0-9a-f]*"
- const: "memory" # 'memory' only allowed for selectingI expect the vast majority of device bindings will not use select at all and rely on compatible string matching.
Quoted 15 lines
Quoted 2 lines
Documentation/devicetree/bindings/example-schema.yaml new file +2
-0+ +properties:[...]
Documentation/devicetree/bindings/example-schema.yaml line 91
Quoted 10 lines
Documentation/devicetree/bindings/example-schema.yaml new file +10
-0+ + interrupts: + # Either 1 or 2 interrupts can be present + minItems: 1 + maxItems: 2 + items: + - description: tx or combined interrupt + - description: rx interrupt + + description: |The '|' is needed to make yaml happy?
Yes, this is simply how you do literal text blocks in yaml.
We don't really need for this one really, but for the top-level 'description' we do. The long term intent is 'description' would be written in sphinx/rst and can be extracted into the DT spec (for common bindings). Grant has experimented with that some.
Quoted 12 lines
Quoted 12 lines
Documentation/devicetree/bindings/example-schema.yaml new file +12
-0+ A variable number of interrupts warrants a description of what conditions + affect the number of interrupts. Otherwise, descriptions on standard + properties are not necessary. + + interrupt-names: + # minItems must be specified here because the default would be 2 + minItems: 1 + items: + - const: "tx irq" + - const: "rx irq" + + # Property names starting with '#' must be quotedQuoted 8 lines
Documentation/devicetree/bindings/example-schema.yaml line 109
Quoted 6 lines
Documentation/devicetree/bindings/example-schema.yaml new file +6
-0+ '#interrupt-cells': + # A simple case where the value must always be '2'. + # The core schema handles that this must be a single integer. + const: 2 + + interrupt-controller: {}Does '{}' mean nothing to see here?
Yes. It's just an empty schema that's always valid.
Quoted 7 lines
Quoted 7 lines
Documentation/devicetree/bindings/example-schema.yaml new file +7
-0+ # The core checks this is a boolean, so just have to list it here to be + # valid for this binding. + + clock-frequency: + # The type is set in the core schema. Per device schema only need to set + # constraints on the possible values. + minimum: 100Quoted 8 lines
Documentation/devicetree/bindings/example-schema.yaml line 120
Quoted 4 lines
Documentation/devicetree/bindings/example-schema.yaml new file +4
-0+ maximum: 400000 + # The value that should be used if the property is not present + default: 200 +The 'default' field is neat. I look forward to the compiler using the schema to insert defaults into the dtb if the properties aren't present in the input file.
Quoted 3 lines
That wasn't really my intention, but it's what the OS should use if property is not present. But at least for required properties, we could certainly do as you suggest.
I understand the thought of 'neat', but it would also add yet one more layer to the "how did this property get into my dtb?" stew.
But more importantly, if this becomes a required part of the kernel build process, is it adding a new required tool (python)? (Or is python already required?) There is resistance to adding new tools.
-Frank
Quoted 54 lines
Quoted 13 lines
Quoted 13 lines
Documentation/devicetree/bindings/example-schema.yaml new file +13
-0+ foo-gpios: + maxItems: 1 + description: A connection of the 'foo' gpio line. + + vendor,int-property: + description: Vendor specific properties must have a description + type: integer # A type is also required + enum: [2, 4, 6, 8, 10] + + vendor,bool-property: + description: Vendor specific properties must have a description + type: boolean +Quoted 8 lines
Documentation/devicetree/bindings/example-schema.yaml line 138
Quoted 5 lines
Documentation/devicetree/bindings/example-schema.yaml new file +5
-0+required: + - compatible + - reg + - interrupts + - interrupt-controllerCan the required or optional parts go under each property instead of having a different section?
No, because then it is not json-schema language.
Quoted 2 lines
Or does that make the schema parser
difficult to implement?Yes, because then we have to implement a schema parser.
Quoted 11 lines
It may also make sense to negate this and
specify only the optional properties, or to require both optional and required lists to make things more explicit at the cost of some verbosity.Documentation/devicetree/bindings/example-schema.yaml line 142
Quoted 4 lines
Documentation/devicetree/bindings/example-schema.yaml new file +4
-0+ +examples: + - | + /{Is the first slash required here?
No, just leftover from being the root node in the example.
Thanks for taking a look.
Quoted 7 lines
Quoted 7 lines
Documentation/devicetree/bindings/example-schema.yaml new file +7
-0+ compatible = "vendor,soc4-ip", "vendor,soc1-ip"; + reg = <0x1000 0x80>, + <0x3000 0x80>; + reg-names = "core", "aux"; + interrupts = <10>; + interrupt-controller; + };
Quoting Rob Herring (2018-04-20 11:15:04)
Quoted 34 lines · Stephen Boyd
Quoted 17 lines
Quoting Rob Herring (2018-04-18 15:29:05)
Quoted 6 lines
Documentation/devicetree/bindings/example-schema.yaml new file +0
-0Documentation/devicetree/bindings/example-schema.yaml line 8
Quoted 8 lines
Documentation/devicetree/bindings/example-schema.yaml new file +8
-0@@ -0,0 +1,149 @@ + + The end of the description is marked by indentation less than the first line + in the description. + +select: false + # 'select' is a schema applied to a DT node to determine if this binding + # schema should be applied to the node. It is optional and by default the + # possible compatible strings are extracted and used to match.Can we get a concrete example here?
select: true
:) Which is apply to every node.
A better one is from the memory node schema ('$nodename' gets added :
select:
required: ["$nodename"]
properties:
$nodename:
oneOf:
- pattern: "^memory@[0-9a-f]*"
- const: "memory" # 'memory' only allowed for selecting
Quoted 2 lines
I expect the vast majority of device bindings will not use select at all and rely on compatible string matching.
Thanks! I was looking to see how the select syntax would work and this shows one example nicely. I suppose another way would be to show how a compatible string would be matched through select, even though it's redundant.
Is there a way we can enforce node names through the schema too? For example to enforce that a clock controller is called 'clock-controller' or a spi master is called 'spi'.
Quoted 17 lines
Quoted 4 lines
Quoted 3 lines
Documentation/devicetree/bindings/example-schema.yaml new file +2
-0+ +properties:[...]
Quoted 12 lines
Documentation/devicetree/bindings/example-schema.yaml line 91
Quoted 10 lines
Documentation/devicetree/bindings/example-schema.yaml new file +10
-0+ + interrupts: + # Either 1 or 2 interrupts can be present + minItems: 1 + maxItems: 2 + items: + - description: tx or combined interrupt + - description: rx interrupt + + description: |The '|' is needed to make yaml happy?
Quoted 6 lines
Yes, this is simply how you do literal text blocks in yaml.
We don't really need for this one really, but for the top-level 'description' we do. The long term intent is 'description' would be written in sphinx/rst and can be extracted into the DT spec (for common bindings). Grant has experimented with that some.
Ok. That sounds cool. Then we could embed links to datasheets and SVGs too.
Quoted 22 lines
Quoted 13 lines
Quoted 13 lines
Documentation/devicetree/bindings/example-schema.yaml new file +12
-0+ A variable number of interrupts warrants a description of what conditions + affect the number of interrupts. Otherwise, descriptions on standard + properties are not necessary. + + interrupt-names: + # minItems must be specified here because the default would be 2 + minItems: 1 + items: + - const: "tx irq" + - const: "rx irq" + + # Property names starting with '#' must be quotedQuoted 8 lines
Documentation/devicetree/bindings/example-schema.yaml line 109
Quoted 6 lines
Documentation/devicetree/bindings/example-schema.yaml new file +6
-0+ '#interrupt-cells': + # A simple case where the value must always be '2'. + # The core schema handles that this must be a single integer. + const: 2 + + interrupt-controller: {}Does '{}' mean nothing to see here?
Quoted 1 line
Yes. It's just an empty schema that's always valid.
Could we include another schema to indicate that this is an interrupt controller? I'm sort of asking for multi-schema inheritance.
Quoted 23 lines
Quoted 14 lines
Quoted 14 lines
Documentation/devicetree/bindings/example-schema.yaml new file +13
-0+ foo-gpios: + maxItems: 1 + description: A connection of the 'foo' gpio line. + + vendor,int-property: + description: Vendor specific properties must have a description + type: integer # A type is also required + enum: [2, 4, 6, 8, 10] + + vendor,bool-property: + description: Vendor specific properties must have a description + type: boolean +Quoted 8 lines
Documentation/devicetree/bindings/example-schema.yaml line 138
Quoted 5 lines
Documentation/devicetree/bindings/example-schema.yaml new file +5
-0+required: + - compatible + - reg + - interrupts + - interrupt-controllerCan the required or optional parts go under each property instead of having a different section?
Quoted 6 lines
No, because then it is not json-schema language.
Quoted 2 lines
Or does that make the schema parser
difficult to implement?Yes, because then we have to implement a schema parser.
:/
Rob Herring
maintainerQuoted 38 lines · Stephen Boyd
Quoting Rob Herring (2018-04-20 11:15:04)
Quoted 34 lines · Stephen Boyd
Quoted 17 lines
Quoting Rob Herring (2018-04-18 15:29:05)
Quoted 6 lines
Documentation/devicetree/bindings/example-schema.yaml new file +0
-0Documentation/devicetree/bindings/example-schema.yaml line 8
Quoted 8 lines
Documentation/devicetree/bindings/example-schema.yaml new file +8
-0@@ -0,0 +1,149 @@ + + The end of the description is marked by indentation less than the first line + in the description. + +select: false + # 'select' is a schema applied to a DT node to determine if this binding + # schema should be applied to the node. It is optional and by default the + # possible compatible strings are extracted and used to match.Can we get a concrete example here?
select: true
:) Which is apply to every node.
A better one is from the memory node schema ('$nodename' gets added :
select:
required: ["$nodename"]
properties:
$nodename:
oneOf:
- pattern: "^memory@[0-9a-f]*"
- const: "memory" # 'memory' only allowed for selectingQuoted 2 lines
I expect the vast majority of device bindings will not use select at all and rely on compatible string matching.
Quoted 8 lines
Thanks! I was looking to see how the select syntax would work and this shows one example nicely. I suppose another way would be to show how a compatible string would be matched through select, even though it's redundant.
Is there a way we can enforce node names through the schema too? For example to enforce that a clock controller is called 'clock-controller' or a spi master is called 'spi'.
Yes, that's something I'd like to do. I think the easiest is to just treat node name as a property. We already generate a $nodename property when parsing the yaml format DT.
Quoted 49 lines
Quoted 17 lines
Quoted 4 lines
Quoted 3 lines
Documentation/devicetree/bindings/example-schema.yaml new file +2
-0+ +properties:[...]
Quoted 12 lines
Documentation/devicetree/bindings/example-schema.yaml line 91
Quoted 10 lines
Documentation/devicetree/bindings/example-schema.yaml new file +10
-0+ + interrupts: + # Either 1 or 2 interrupts can be present + minItems: 1 + maxItems: 2 + items: + - description: tx or combined interrupt + - description: rx interrupt + + description: |The '|' is needed to make yaml happy?
Quoted 6 lines
Yes, this is simply how you do literal text blocks in yaml.
We don't really need for this one really, but for the top-level 'description' we do. The long term intent is 'description' would be written in sphinx/rst and can be extracted into the DT spec (for common bindings). Grant has experimented with that some.
Ok. That sounds cool. Then we could embed links to datasheets and SVGs too.
Quoted 22 lines
Quoted 21 lines
Quoted 9 lines
Documentation/devicetree/bindings/example-schema.yaml new file +8
-0+ A variable number of interrupts warrants a description of what conditions + affect the number of interrupts. Otherwise, descriptions on standard + properties are not necessary. + + interrupt-names: + # minItems must be specified here because the default would be 2 + minItems: 1 + items:Documentation/devicetree/bindings/example-schema.yaml line 109
Quoted 10 lines
Documentation/devicetree/bindings/example-schema.yaml new file +10
-0+ - const: "tx irq" + - const: "rx irq" + + # Property names starting with '#' must be quoted + '#interrupt-cells': + # A simple case where the value must always be '2'. + # The core schema handles that this must be a single integer. + const: 2 + + interrupt-controller: {}Does '{}' mean nothing to see here?
Quoted 4 lines
Quoted 1 line
Yes. It's just an empty schema that's always valid.
Could we include another schema to indicate that this is an interrupt controller? I'm sort of asking for multi-schema inheritance.
Yes, but there's no need to do that here. Another schema can select on "interrupt-controller" property and be applied independently. There's already an example of that for the root node in my yaml-bindings repo.
Rob
Quoted 8 lines · Stephen Boyd
Quoting Rob Herring (2018-04-20 11:15:04)
Quoted 7 lines · Stephen Boyd
Quoted 6 lines
Quoting Rob Herring (2018-04-18 15:29:05)
Quoted 5 lines
Documentation/devicetree/bindings/example-schema.yaml new file +0
-0
[...]
Quoted 14 lines
Quoted 14 lines
Quoted 11 lines
Documentation/devicetree/bindings/example-schema.yaml line 91
Quoted 9 lines
Documentation/devicetree/bindings/example-schema.yaml new file +9
-0+ interrupts: + # Either 1 or 2 interrupts can be present + minItems: 1 + maxItems: 2 + items: + - description: tx or combined interrupt + - description: rx interrupt + + description: |The '|' is needed to make yaml happy?
Yes, this is simply how you do literal text blocks in yaml.
Quoted 7 lines
Quoted 4 lines
We don't really need for this one really, but for the top-level 'description' we do. The long term intent is 'description' would be written in sphinx/rst and can be extracted into the DT spec (for common bindings). Grant has experimented with that some.
Ok. That sounds cool. Then we could embed links to datasheets and SVGs too.
I'd like it if we can define the description text blocks to be reStructeredText markup. That makes it even easier to integrate with the specification documentation.
[...]
Quoted 11 lines
Quoted 11 lines
Quoted 9 lines
Documentation/devicetree/bindings/example-schema.yaml line 109
Quoted 7 lines
Documentation/devicetree/bindings/example-schema.yaml new file +7
-0+ # Property names starting with '#' must be quoted + '#interrupt-cells': + # A simple case where the value must always be '2'. + # The core schema handles that this must be a single integer. + const: 2 + + interrupt-controller: {}Does '{}' mean nothing to see here?
Yes. It's just an empty schema that's always valid.
IIRC, in the current jsonschema draft-6 spec, the following also has the same behaviour, which I like slightly better:
interrupt-controller: true
g.
IMPORTANT NOTICE: The contents of this email and any attachments are confidential and may also be privileged. If you are not the intended recipient, please notify the sender immediately and do not disclose the contents to any other person, use it for any purpose, or store or copy the information in any medium. Thank you.
Rob Herring
maintainerQuoted 39 lines · Grant Likely
Quoted 13 lines · Stephen Boyd
Quoting Rob Herring (2018-04-20 11:15:04)
Quoted 11 lines · Stephen Boyd
Quoted 9 lines
Quoting Rob Herring (2018-04-18 15:29:05)
Quoted 7 lines
Documentation/devicetree/bindings/example-schema.yaml new file +0
-0[...]
Quoted 23 lines
Quoted 21 lines
Quoted 12 lines
Documentation/devicetree/bindings/example-schema.yaml line 91
Quoted 10 lines
Documentation/devicetree/bindings/example-schema.yaml new file +9
-0+ interrupts: + # Either 1 or 2 interrupts can be present + minItems: 1 + maxItems: 2 + items: + - description: tx or combined interrupt + - description: rx interrupt + + description: |Quoted 1 line
The '|' is needed to make yaml happy?
Yes, this is simply how you do literal text blocks in yaml.
We don't really need for this one really, but for the top-level 'description' we do. The long term intent is 'description' would be written in sphinx/rst and can be extracted into the DT spec (for common bindings). Grant has experimented with that some.
Quoted 7 lines
Quoted 2 lines
Ok. That sounds cool. Then we could embed links to datasheets and SVGs too.
I'd like it if we can define the description text blocks to be reStructeredText markup. That makes it even easier to integrate with the specification documentation.
I think that's going to require thinking about how each binding is integrated into the spec. We're only talking about common bindings I presume, but still we have no model defined. For example, with properties, I'd assume we'd want to generate a table of properties and we wouldn't want the property descriptions in rST because the description becomes just a cell in the table. So we need some sort of template.
Also, how do we validate that description contains valid rST? No point requiring it until we can validate it.
Quoted 14 lines
[...]
Quoted 13 lines
Quoted 13 lines
Quoted 11 lines
Documentation/devicetree/bindings/example-schema.yaml line 109
Quoted 8 lines
Documentation/devicetree/bindings/example-schema.yaml new file +7
-0+ # Property names starting with '#' must be quoted + '#interrupt-cells': + # A simple case where the value must always be '2'. + # The core schema handles that this must be a single integer. + const: 2 + + interrupt-controller: {}Does '{}' mean nothing to see here?
Quoted 6 lines
Quoted 1 line
Quoted 1 line
Yes. It's just an empty schema that's always valid.
IIRC, in the current jsonschema draft-6 spec, the following also has the same behaviour, which I like slightly better:
interrupt-controller: true
They are not exactly the same. '{}' is a schema object and 'true' is just a boolean. But yes, it can work. We need to drop "type: object" from meta-schemas/boolean.yaml and it will work.
Rob
Quoted 56 lines · Rob Herring
Quoted 39 lines · Grant Likely
Quoted 13 lines · Stephen Boyd
Quoting Rob Herring (2018-04-20 11:15:04)
Quoted 11 lines · Stephen Boyd
Quoted 9 lines
Quoting Rob Herring (2018-04-18 15:29:05)
Quoted 7 lines
Documentation/devicetree/bindings/example-schema.yaml new file +0
-0[...]
Quoted 23 lines
Quoted 21 lines
Quoted 12 lines
Documentation/devicetree/bindings/example-schema.yaml line 91
Quoted 10 lines
Documentation/devicetree/bindings/example-schema.yaml new file +9
-0+ interrupts: + # Either 1 or 2 interrupts can be present + minItems: 1 + maxItems: 2 + items: + - description: tx or combined interrupt + - description: rx interrupt + + description: |Quoted 1 line
The '|' is needed to make yaml happy?
Yes, this is simply how you do literal text blocks in yaml.
We don't really need for this one really, but for the top-level 'description' we do. The long term intent is 'description' would be written in sphinx/rst and can be extracted into the DT spec (for common bindings). Grant has experimented with that some.
Quoted 7 lines
Quoted 2 lines
Ok. That sounds cool. Then we could embed links to datasheets and SVGs too.
I'd like it if we can define the description text blocks to be reStructeredText markup. That makes it even easier to integrate with the specification documentation.
I think that's going to require thinking about how each binding is integrated into the spec. We're only talking about common bindings I presume, but still we have no model defined. For example, with properties, I'd assume we'd want to generate a table of properties and we wouldn't want the property descriptions in rST because the description becomes just a cell in the table. So we need some sort of template.
Quoted 2 lines
Also, how do we validate that description contains valid rST? No point requiring it until we can validate it.
Indeed. Part of that was me thinking outloud. Need to actually get it working before adding constraints.
g.
IMPORTANT NOTICE: The contents of this email and any attachments are confidential and may also be privileged. If you are not the intended recipient, please notify the sender immediately and do not disclose the contents to any other person, use it for any purpose, or store or copy the information in any medium. Thank you.
Quoted 7 lines · Rob Herring
The current DT binding documentation format of freeform text is painful to write, review, validate and maintain.
This is just an example of what a binding in the schema format looks like. It's using jsonschema vocabulary in a YAML encoded document. Using jsonschema gives us access to existing tooling. A YAML encoding gives us something easy to edit.
It'd be useful to see some examples of how things like including by reference other schema work. It feels like something we should be able to use more in a schema based thing but perhaps that's not viable with realistic tooling. In general this looks OK, especially with all the meta comments about the language stripped out.
Documentation/devicetree/bindings/example-schema.yaml line 92
Quoted 2 lines
Documentation/devicetree/bindings/example-schema.yaml new file +2
-0+ description: | + A variable number of interrupts warrants a description of what conditions
Like Stephen said the | looks odd.
Documentation/devicetree/bindings/example-schema.yaml line 101
Quoted 6 lines
Documentation/devicetree/bindings/example-schema.yaml new file +6
-0+ interrupt-names: + # minItems must be specified here because the default would be 2 + minItems: 1 + items: + - const: "tx irq" + - const: "rx irq"
Any way to relate this to the interrupts property in the schema language (eg, must have the less or equal number of elements)?
Quoted 1 line
+ # Property names starting with '#' must be quoted
That's awkward :/ Perhaps just by convention quote all property names for simplicity?
Rob Herring
maintainerQuoted 9 lines · Mark Brown
Quoted 7 lines · Rob Herring
The current DT binding documentation format of freeform text is painful to write, review, validate and maintain.
This is just an example of what a binding in the schema format looks like. It's using jsonschema vocabulary in a YAML encoded document. Using jsonschema gives us access to existing tooling. A YAML encoding gives us something easy to edit.
Quoted 5 lines
It'd be useful to see some examples of how things like including by reference other schema work. It feels like something we should be able to use more in a schema based thing but perhaps that's not viable with realistic tooling. In general this looks OK, especially with all the meta comments about the language stripped out.
There are several examples in the meta-schema and some of the core schema as references are used there quite a bit. It gets quite fun to follow with recursion. :)
I think the need for references in device bindings should be pretty minimal. We'd probably mainly need references for some vendor specific properties which will need to reference some of our compound types. So we'd have something like this:
vendor,a-string-array-prop:
$ref: "dt-core.yaml#/definitions/proptypes/stringarray"
For common bindings, we don't have to reference them in device bindings (which should save lots of boilerplate). We can select and apply them based on presence of properties and that happens independent of the device binding. The device binding only needs define what the common binding cannot which is typically how many elements and what are they.
Quoted 5 lines
Documentation/devicetree/bindings/example-schema.yaml line 92
Quoted 3 lines
Documentation/devicetree/bindings/example-schema.yaml new file +2
-0+ description: | + A variable number of interrupts warrants a description of what conditionsLike Stephen said the | looks odd.
That's just how literal blocks in yaml are done.
Quoted 9 lines
Documentation/devicetree/bindings/example-schema.yaml line 101
Quoted 6 lines
Documentation/devicetree/bindings/example-schema.yaml new file +6
-0+ interrupt-names: + # minItems must be specified here because the default would be 2 + minItems: 1 + items: + - const: "tx irq" + - const: "rx irq"Any way to relate this to the interrupts property in the schema language (eg, must have the less or equal number of elements)?
I've wanted something like that, but there isn't any way that I've come up with. Generally, the "jsonschema way" is each schema is supposed to be independent of each other. There's some discussion about adding data dependent schema which might help in this case.
Quoted 5 lines
Quoted 2 lines
+ # Property names starting with '#' must be quoted
That's awkward :/ Perhaps just by convention quote all property names for simplicity?
Yes, perhaps we should. I have a formatting tool, I'll look into whether i can make it do that.
Thanks for taking a look.
Rob
Hi Rob,
Thanks for the example. It was a good starting tutorial of sorts for me to understand the format a bit.
Documentation/devicetree/bindings/example-schema.yaml
Quoted 35 lines · Rob Herring
The current DT binding documentation format of freeform text is painful to write, review, validate and maintain.
This is just an example of what a binding in the schema format looks like. It's using jsonschema vocabulary in a YAML encoded document. Using jsonschema gives us access to existing tooling. A YAML encoding gives us something easy to edit.
This example is just the tip of the iceberg, but it the part most developers writing bindings will interact with. Backing all this up are meta-schema (to validate the binding schemas), some DT core schema, YAML encoded DT output with dtc, and a small number of python scripts to run validation. The gory details including how to run end-to-end validation can be found here:
https://www.spinics.net/lists/devicetree-spec/msg00649.html
Signed-off-by Rob Herring <[email protected]>---
Cc list,
You all review and/or write lots of binding documents. I'd like some feedback on the format.Thanks,
Rob.../devicetree/bindings/example-schema.yaml | 149 +++++++++++++++++++++ 1 file changed, 149 insertions(+) create mode 100644 Documentation/devicetree/bindings/example-schema.yamlDocumentation/devicetree/bindings/example-schema.yaml new file +0
-0
I'm guessing by the path name that this is in the Linux kernel source tree.
Documentation/devicetree/bindings/example-schema.yaml line 1
Quoted 2 lines
Documentation/devicetree/bindings/example-schema.yaml new file +1
-0@@ -0,0 +1,149 @@ +# SPDX-License-Identifier: BSD-2-Clause
If in the Linux kernel source tree, then allow gpl-v2 as a possible license.
Documentation/devicetree/bindings/example-schema.yaml line 8
Quoted 7 lines
Documentation/devicetree/bindings/example-schema.yaml new file +7
-0+# Copyright 2018 Linaro Ltd. +%YAML 1.2 +--- +# All the top-level keys are standard json-schema keywords except for +# 'maintainers' and 'select' + +# $id is a unique idenifier based on the filename
^^^^^^^^^ identifier
Documentation/devicetree/bindings/example-schema.yaml line 9
Quoted 1 line
Documentation/devicetree/bindings/example-schema.yaml new file +1
-0+$id: "http://devicetree.org/schemas/example-schema.yaml#"
Does this imply that all schemas will be at devicetree.org instead of in the Linux kernel source tree? This would be counter to my earlier guess about where this patch is applied.
Documentation/devicetree/bindings/example-schema.yaml line 10
Quoted 1 line
Documentation/devicetree/bindings/example-schema.yaml new file +1
-0+$schema: "http://devicetree.org/meta-schemas/core.yaml#"
How is $schema used? Is it accessed across the network?
Quoted 11 lines
Documentation/devicetree/bindings/example-schema.yaml new file +11
-0+ +# Only 1 version supported for now +version: 1 + +title: An example schema annotated with jsonschema details + +maintainers: + - Rob Herring <[email protected]> + +description: | + A more detailed multi-line description of the binding.
Documentation/devicetree/bindings/example-schema.yaml line 31
Quoted 10 lines
Documentation/devicetree/bindings/example-schema.yaml new file +10
-0+ + Details about the hardware device and any links to datasheets can go here. + + The end of the description is marked by indentation less than the first line + in the description. + +select: false + # 'select' is a schema applied to a DT node to determine if this binding + # schema should be applied to the node. It is optional and by default the + # possible compatible strings are extracted and used to match.
My first reaction was that 'node' should somehow be included in the name of 'select'. But my second thought was that maybe 'node' is implied, because every schema file describes a single node??? This is where my lack of knowledge kicks in - I'll go read stuff in your yaml-bindings repo to get a better background...
Quoted 18 lines
Documentation/devicetree/bindings/example-schema.yaml new file +18
-0+ +properties: + # A dictionary of DT properties for this binding schema + compatible: + # More complicated schema can use oneOf (XOR), anyOf (OR), or allOf (AND) + # to handle different conditions. + # In this case, it's needed to handle a variable number of values as there + # isn't another way to express a constraint of the last string value. + # The boolean schema must be a list of schemas. + oneOf: + - items: + # items is a list of possible values for the property. The number of + # values is determined by the number of elements in the list. + # Order in lists is significant, order in dicts is not + # Must be one of the 1st enums followed by the 2nd enum + # + # Each element in items should be 'enum' or 'const' + - enum:
Documentation/devicetree/bindings/example-schema.yaml line 59
Quoted 10 lines
Documentation/devicetree/bindings/example-schema.yaml new file +10
-0+ - vendor,soc4-ip + - vendor,soc3-ip + - vendor,soc2-ip + - enum: + - vendor,soc1-ip + # additionalItems being false is implied + # minItems/maxItems equal to 2 is implied + - items: + # 'const' is just a special case of an enum with a single possible value + - const: vendor,soc1-ip
I'm using this as an example of a concept, not to pick on this one specific instance.
One of my concerns with YAML has been the rich, flexible syntax available. To a YAML expert, this is a very useful feature. To someone who does not use YAML and will not use it for anything other than binding schemas, this adds more complexity.
What I have heard some people say in the validation discussions is that the allowed YAML syntax for binding schemas would be limited to one (or a very small number) of the possible YAML alternative syntaxes for use in the bindings. Will there be a document describing such a limitation on alternate syntaxes?
(This example file provides a good example of a single syntax style, but does not preclude other equivalent syntax.)
Getting back to the specific example of 'const', it is a less verbose way of specifying a single value enum, and I think it looks cleaner and more readable. But it is also a case of adding more complexity for someone who does not otherwise use YAML. I would using the more verbose syntax of enum even for a single possible value.
Quoted 7 lines
Documentation/devicetree/bindings/example-schema.yaml new file +7
-0+ + reg: + # The description of each element defines the order and implicitly defines + # the number of reg entries + items: + - description: core registers + - description: aux registers
Documentation/devicetree/bindings/example-schema.yaml line 76
Quoted 10 lines
Documentation/devicetree/bindings/example-schema.yaml new file +10
-0+ # minItems/maxItems equal to 2 is implied + + reg-names: + # The core schema enforces this is a string array + items: + - const: core + - const: aux + + clocks: + # Only a single entry, so just need to set the max number of items.
# More restrictions are provided in meta-schemas/clocks.yaml
Quoted 12 lines
Documentation/devicetree/bindings/example-schema.yaml new file +12
-0+ maxItems: 1 + + clock-names: + items: + - const: bus + + interrupts: + # Either 1 or 2 interrupts can be present + minItems: 1 + maxItems: 2 + items: + - description: tx or combined interrupt
Documentation/devicetree/bindings/example-schema.yaml line 98
Quoted 10 lines
Documentation/devicetree/bindings/example-schema.yaml new file +10
-0+ - description: rx interrupt + + description: | + A variable number of interrupts warrants a description of what conditions + affect the number of interrupts. Otherwise, descriptions on standard + properties are not necessary. + + interrupt-names: + # minItems must be specified here because the default would be 2 + minItems: 1
Why the difference between the interrupts property and the interrupt-names property (specifying maxItems for interrupt, but not interrupt-names)?
Others have already commented on a desire to have a way to specify that number of interrupts should match number of interrupt-names.
Quoted 11 lines
Documentation/devicetree/bindings/example-schema.yaml new file +11
-0+ items: + - const: "tx irq" + - const: "rx irq" + + # Property names starting with '#' must be quoted + '#interrupt-cells': + # A simple case where the value must always be '2'. + # The core schema handles that this must be a single integer. + const: 2 + + interrupt-controller: {}
Documentation/devicetree/bindings/example-schema.yaml line 119
Quoted 10 lines
Documentation/devicetree/bindings/example-schema.yaml new file +10
-0+ # The core checks this is a boolean, so just have to list it here to be + # valid for this binding. + + clock-frequency: + # The type is set in the core schema. Per device schema only need to set + # constraints on the possible values. + minimum: 100 + maximum: 400000 + # The value that should be used if the property is not present + default: 200
This is confusing to me. (Beyond the discussion of this in Stephen Boyd's reply...) My naive reading of this is that the default is the value that the driver should implement if the property is missing, which is unrelated to the concept of validating a dts file.
Quoted 33 lines
Documentation/devicetree/bindings/example-schema.yaml new file +30
-1+ + foo-gpios: + maxItems: 1 + description: A connection of the 'foo' gpio line. + + vendor,int-property: + description: Vendor specific properties must have a description + type: integer # A type is also required + enum: [2, 4, 6, 8, 10] + + vendor,bool-property: + description: Vendor specific properties must have a description + type: boolean + +required: + - compatible + - reg + - interrupts + - interrupt-controller + +examples: + - | + /{ + compatible = "vendor,soc4-ip", "vendor,soc1-ip"; + reg = <0x1000 0x80>, + <0x3000 0x80>; + reg-names = "core", "aux"; + interrupts = <10>; + interrupt-controller; + }; --2.14.1
Rob Herring
maintainerQuoted 37 lines · Frank Rowand
Hi Rob,
Thanks for the example. It was a good starting tutorial of sorts for me to understand the format a bit.
Quoted 30 lines · Rob Herring
The current DT binding documentation format of freeform text is painful to write, review, validate and maintain.
This is just an example of what a binding in the schema format looks like. It's using jsonschema vocabulary in a YAML encoded document. Using jsonschema gives us access to existing tooling. A YAML encoding gives us something easy to edit.
This example is just the tip of the iceberg, but it the part most developers writing bindings will interact with. Backing all this up are meta-schema (to validate the binding schemas), some DT core schema, YAML encoded DT output with dtc, and a small number of python scripts to run validation. The gory details including how to run end-to-end validation can be found here:
https://www.spinics.net/lists/devicetree-spec/msg00649.html
Signed-off-by Rob Herring <[email protected]>---
Cc list,
You all review and/or write lots of binding documents. I'd like some feedback on the format.Thanks,
Rob.../devicetree/bindings/example-schema.yaml | 149 +++++++++++++++++++++ 1 file changed, 149 insertions(+) create mode 100644 Documentation/devicetree/bindings/example-schema.yaml
Quoted 7 lines
Documentation/devicetree/bindings/example-schema.yaml
Quoted 5 lines
Documentation/devicetree/bindings/example-schema.yaml new file +0
-0I'm guessing by the path name that this is in the Linux kernel source tree.
Yes, well, my kernel tree. Most of the work still lives here:
https://github.com/robherring/yaml-bindings/
Quoted 4 lines
Documentation/devicetree/bindings/example-schema.yaml line 1
Quoted 2 lines
Documentation/devicetree/bindings/example-schema.yaml new file +1
-0@@ -0,0 +1,149 @@ +# SPDX-License-Identifier: BSD-2-ClauseIf in the Linux kernel source tree, then allow gpl-v2 as a possible license.
Why? BSD is compatible. The license of the above repo is all BSD.
Of course there's all the existing docs which default to GPLv2 and we'll probably have to maintain that.
Quoted 10 lines
Documentation/devicetree/bindings/example-schema.yaml line 8
Quoted 7 lines
Documentation/devicetree/bindings/example-schema.yaml new file +7
-0+# Copyright 2018 Linaro Ltd. +%YAML 1.2 +--- +# All the top-level keys are standard json-schema keywords except for +# 'maintainers' and 'select' + +# $id is a unique idenifier based on the filename^^^^^^^^^ identifier
Quoted 5 lines
Documentation/devicetree/bindings/example-schema.yaml line 9
Quoted 1 line
Documentation/devicetree/bindings/example-schema.yaml new file +1
-0+$id: "http://devicetree.org/schemas/example-schema.yaml#"Does this imply that all schemas will be at devicetree.org instead of in the Linux kernel source tree? This would be counter to my earlier guess about where this patch is applied.
They could be, but not necessarily. This is just convention in jsonschema is the best I understand it.
I don't think you'd want validation to require an internet connection. For the base meta-schema, for example, it does exist at
http://json-schema.org/draft-06/schema, but that's also distributed with implementations of jsonschema validators.
A large part (not that any part is large) of the tools Grant and I have written is doing the cross reference resolution of files which uses the $id field.
Quoted 3 lines
Documentation/devicetree/bindings/example-schema.yaml line 10
Quoted 1 line
Documentation/devicetree/bindings/example-schema.yaml new file +1
-0+$schema: "http://devicetree.org/meta-schemas/core.yaml#"How is $schema used?
Tells the validator what meta-schema this schema follows. Typically you see draft04 or draft06 here if you haven't written a meta-schema.
Quoted 1 line
Is it accessed across the network?
Could be, but generally no.
Quoted 19 lines
Quoted 19 lines
Documentation/devicetree/bindings/example-schema.yaml new file +19
-0+ +# Only 1 version supported for now +version: 1 + +title: An example schema annotated with jsonschema details + +maintainers: + - Rob Herring <[email protected]> + +description: | + A more detailed multi-line description of the binding. + + Details about the hardware device and any links to datasheets can go here. + + The end of the description is marked by indentation less than the first line + in the description. + +select: false + # 'select' is a schema applied to a DT node to determine if this binding
Quoted 8 lines
Documentation/devicetree/bindings/example-schema.yaml line 31
Quoted 2 lines
Documentation/devicetree/bindings/example-schema.yaml new file +2
-0+ # schema should be applied to the node. It is optional and by default the + # possible compatible strings are extracted and used to match.My first reaction was that 'node' should somehow be included in the name of 'select'. But my second thought was that maybe 'node' is implied, because every schema file describes a single node??? This is where my lack of knowledge kicks in - I'll go read stuff in your yaml-bindings repo to get a better background...
Yes, schema are applied to nodes and most of the current uses of select are based on node name. We walk the DT and apply all the schema for a node that select (either in the doc or generated from compatible) is valid.
Quoted 32 lines
Quoted 18 lines
Documentation/devicetree/bindings/example-schema.yaml new file +18
-0+ +properties: + # A dictionary of DT properties for this binding schema + compatible: + # More complicated schema can use oneOf (XOR), anyOf (OR), or allOf (AND) + # to handle different conditions. + # In this case, it's needed to handle a variable number of values as there + # isn't another way to express a constraint of the last string value. + # The boolean schema must be a list of schemas. + oneOf: + - items: + # items is a list of possible values for the property. The number of + # values is determined by the number of elements in the list. + # Order in lists is significant, order in dicts is not + # Must be one of the 1st enums followed by the 2nd enum + # + # Each element in items should be 'enum' or 'const' + - enum:Documentation/devicetree/bindings/example-schema.yaml line 59
Quoted 10 lines
Documentation/devicetree/bindings/example-schema.yaml new file +10
-0+ - vendor,soc4-ip + - vendor,soc3-ip + - vendor,soc2-ip + - enum: + - vendor,soc1-ip + # additionalItems being false is implied + # minItems/maxItems equal to 2 is implied + - items: + # 'const' is just a special case of an enum with a single possible value + - const: vendor,soc1-ipI'm using this as an example of a concept, not to pick on this one specific instance.
Quoted 4 lines
One of my concerns with YAML has been the rich, flexible syntax available. To a YAML expert, this is a very useful feature. To someone who does not use YAML and will not use it for anything other than binding schemas, this adds more complexity.
I think you need to replace YAML with jsonschema. Our YAML use is restricted to the subset of which JSON supports (plus the literal block support which I think can't be done in JSON). And then the vocabulary we are using is jsonschema.
I share the concern as I doubt most kernel developers don't know jsonschema. But then the alternative is us defining and writing our own thing which is C like 'cause that's what kernel developers understand. My hope is to simplify and restrict things enough that it writing a binding doc is straightforward without being jsonschema experts. That was the intent of this patch without going into all the details behind it.
Quoted 5 lines
What I have heard some people say in the validation discussions is that the allowed YAML syntax for binding schemas would be limited to one (or a very small number) of the possible YAML alternative syntaxes for use in the bindings. Will there be a document describing such a limitation on alternate syntaxes?
The syntax is jsonschema. That's what defines the top-level fields for the most part. For common properties, the syntax is pretty locked down by what the meta-schema allows. So for example the following will fail on the meta-schema even though something like this is valid jsonschema:
compatible:
allOf:
- items:
- enum: [ foo ]
- items:
- enum: [ bar ]
Jsonschema has the "feature" that if the validator doesn't recognize a keyword, it is supposed to silently ignore the keyword. So a typo in a keyword would just be ignored. The meta-schema
Quoted 3 lines
(This example file provides a good example of a single syntax style, but does not preclude other equivalent syntax.)
There's also a question of formatting. For example, we can have:
enum: [1,2,3]
or
enum:
- 1
- 2
- 3
IMO, we should lock that down too.
Quoted 5 lines
Getting back to the specific example of 'const', it is a less verbose way of specifying a single value enum, and I think it looks cleaner and more readable. But it is also a case of adding more complexity for someone who does not otherwise use YAML. I would using the more verbose syntax of enum even for a single possible value.
That's fine. There's certainly cases where we might start with 1 value and plan to add more over time and would want to use enum.
Quoted 38 lines
Quoted 7 lines
Documentation/devicetree/bindings/example-schema.yaml new file +7
-0+ + reg: + # The description of each element defines the order and implicitly defines + # the number of reg entries + items: + - description: core registers + - description: aux registersDocumentation/devicetree/bindings/example-schema.yaml line 76
Quoted 10 lines
Documentation/devicetree/bindings/example-schema.yaml new file +10
-0+ # minItems/maxItems equal to 2 is implied + + reg-names: + # The core schema enforces this is a string array + items: + - const: core + - const: aux + + clocks: + # Only a single entry, so just need to set the max number of items.# More restrictions are provided in
meta-schemas/clocks.yamlQuoted 17 lines
Documentation/devicetree/bindings/example-schema.yaml new file +17
-0+ maxItems: 1 + + clock-names: + items: + - const: bus + + interrupts: + # Either 1 or 2 interrupts can be present + minItems: 1 + maxItems: 2 + items: + - description: tx or combined interrupt + - description: rx interrupt + + description: | + A variable number of interrupts warrants a description of what conditions + affect the number of interrupts. Otherwise, descriptions on standard
Quoted 8 lines
Documentation/devicetree/bindings/example-schema.yaml line 98
Quoted 5 lines
Documentation/devicetree/bindings/example-schema.yaml new file +5
-0+ properties are not necessary. + + interrupt-names: + # minItems must be specified here because the default would be 2 + minItems: 1Why the difference between the interrupts property and the interrupt-names property (specifying maxItems for interrupt, but not interrupt-names)?
I should probably have maxItems here too.
Quoted 2 lines
Others have already commented on a desire to have a way to specify that number of interrupts should match number of interrupt-names.
Yeah, but I don't see a way to do that. You could stick the array size constraints in a common definition and have a $ref to that definition from both, but that doesn't really save you too much.
Quoted 18 lines
Quoted 18 lines
Documentation/devicetree/bindings/example-schema.yaml new file +18
-0+ items: + - const: "tx irq" + - const: "rx irq" + + # Property names starting with '#' must be quoted + '#interrupt-cells': + # A simple case where the value must always be '2'. + # The core schema handles that this must be a single integer. + const: 2 + + interrupt-controller: {} + # The core checks this is a boolean, so just have to list it here to be + # valid for this binding. + + clock-frequency: + # The type is set in the core schema. Per device schema only need to set + # constraints on the possible values. + minimum: 100
Quoted 8 lines
Documentation/devicetree/bindings/example-schema.yaml line 119
Quoted 3 lines
Documentation/devicetree/bindings/example-schema.yaml new file +3
-0+ maximum: 400000 + # The value that should be used if the property is not present + default: 200This is confusing to me. (Beyond the discussion of this in Stephen Boyd's reply...) My naive reading of this is that the default is the value that the driver should implement if the property is missing, which is unrelated to the concept of validating a dts file.
Your reading was my intent and what we currently document. Stephen's suggestion is probably more inline with typical jsonschema use of default (i.e. to fill in missing data).
The schema doc is for more than just dts validation.
Rob
Hi Rob,
Quoted 7 lines · Rob Herring
Quoted 2 lines · Frank Rowand
Others have already commented on a desire to have a way to specify that number of interrupts should match number of interrupt-names.
Yeah, but I don't see a way to do that. You could stick the array size constraints in a common definition and have a $ref to that definition from both, but that doesn't really save you too much.
As Bjorn said, this could be handled in the validation tool, for the myriad of standard list properties that have an accompanying names property.
That avoids having to specify the relation in each and every binding document.
Gr{oetje,eeting}s,
Geert
Signature · 5 lines
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- [email protected] In personal conversations with technical people, I call myself a hacker. But when I'm talking to journalists I just say "programmer" or something like that. -- Linus Torvalds
Quoted 89 lines · Rob Herring
Quoted 37 lines · Frank Rowand
Hi Rob,
Thanks for the example. It was a good starting tutorial of sorts for me to understand the format a bit.
Quoted 30 lines · Rob Herring
The current DT binding documentation format of freeform text is painful to write, review, validate and maintain.
This is just an example of what a binding in the schema format looks like. It's using jsonschema vocabulary in a YAML encoded document. Using jsonschema gives us access to existing tooling. A YAML encoding gives us something easy to edit.
This example is just the tip of the iceberg, but it the part most developers writing bindings will interact with. Backing all this up are meta-schema (to validate the binding schemas), some DT core schema, YAML encoded DT output with dtc, and a small number of python scripts to run validation. The gory details including how to run end-to-end validation can be found here:
https://www.spinics.net/lists/devicetree-spec/msg00649.html
Signed-off-by Rob Herring <[email protected]>---
Cc list,
You all review and/or write lots of binding documents. I'd like some feedback on the format.Thanks,
Rob.../devicetree/bindings/example-schema.yaml | 149 +++++++++++++++++++++ 1 file changed, 149 insertions(+)create mode 100644
Documentation/devicetree/bindings/example-schema.yamlQuoted 7 lines
Documentation/devicetree/bindings/example-schema.yaml
Quoted 5 lines
Documentation/devicetree/bindings/example-schema.yaml new file +0
-0I'm guessing by the path name that this is in the Linux kernel source tree.
Yes, well, my kernel tree. Most of the work still lives here:
https://github.com/robherring/yaml-bindings/
Quoted 4 lines
Documentation/devicetree/bindings/example-schema.yaml line 1
Quoted 2 lines
Documentation/devicetree/bindings/example-schema.yaml new file +1
-0@@ -0,0 +1,149 @@ +# SPDX-License-Identifier: BSD-2-ClauseIf in the Linux kernel source tree, then allow gpl-v2 as a possible license.
Why? BSD is compatible. The license of the above repo is all BSD.
Of course there's all the existing docs which default to GPLv2 and we'll probably have to maintain that.
Quoted 10 lines
Documentation/devicetree/bindings/example-schema.yaml line 8
Quoted 7 lines
Documentation/devicetree/bindings/example-schema.yaml new file +7
-0+# Copyright 2018 Linaro Ltd. +%YAML 1.2 +--- +# All the top-level keys are standard json-schema keywords except for +# 'maintainers' and 'select' + +# $id is a unique idenifier based on the filename^^^^^^^^^ identifierQuoted 5 lines
Documentation/devicetree/bindings/example-schema.yaml line 9
Quoted 1 line
Documentation/devicetree/bindings/example-schema.yaml new file +1
-0+$id: "http://devicetree.org/schemas/example-schema.yaml#"Does this imply that all schemas will be at devicetree.org instead of in the Linux kernel source tree? This would be counter to my earlier guess about where this patch is applied.
They could be, but not necessarily. This is just convention in jsonschema is the best I understand it.
I don't think you'd want validation to require an internet connection. For the base meta-schema, for example, it does exist at
http://json-schema.org/draft-06/schema, but that's also distributed with implementations of jsonschema validators.A large part (not that any part is large) of the tools Grant and I have written is doing the cross reference resolution of files which uses the $id field.
Quoted 6 lines
Quoted 3 lines
Documentation/devicetree/bindings/example-schema.yaml line 10
Quoted 1 line
Documentation/devicetree/bindings/example-schema.yaml new file +1
-0+$schema: "http://devicetree.org/meta-schemas/core.yaml#"How is $schema used?
Tells the validator what meta-schema this schema follows. Typically you see draft04 or draft06 here if you haven't written a meta-schema.
On this topic, we should probably do the same thing for the dt metaschemas. I didn't worry about it initially because there was a lot of working out what it should look like, but we should include a revision number in the DT metaschema $id URLs.
Quoted 3 lines
Quoted 1 line
Is it accessed across the network?
Could be, but generally no.
The $schema and $id values are used as unique identifiers. The parser is setup to look locally for both devicetree.org and json-schema.org URLs, so network access is not used. The parser /can/ fetch a URL over the network, but that isn't a feature we want to use.
Using the http://devicetree.org/ prefix makes sense for the metaschema, and for all the schema files because I think the desire is to have a common database for all users. For practical reasons it makes sense to start with putting them in the Linux kernel tree, but only because that's where all the binding documents currently are. However, we also have the DT rebasing tree that is tracking mainline and has a good structure. We can start encouraging non-Linux users to base off the -rebasing tree, and work on transition plans to allow patches against -rebasing, and to eventually make it the master tree instead of the kernel.
It is also possible to have other prefixes for schemas that don't belong in the common repo (but I cannot think of many good reasons for doing that).
Quoted 8 lines
Quoted 3 lines
(This example file provides a good example of a single syntax style, but does not preclude other equivalent syntax.)
There's also a question of formatting. For example, we can have:
enum: [1,2,3]
Quoted 8 lines
or
enum:
- 1
- 2
- 3IMO, we should lock that down too.
I don't think this level of variance needs to be locked down. That is a very basic example of standard YAML encoding of lists. There are times when one will look better than the other, and it isn't a lot different from the kinds of things we do in C. For example:
int a;
int b;
vs.
int a, b;
On Jsonschema vocabulary? Yes, start with it restricted because there may be unintended consequences. But for YAML syntax, I would rely on the metaschema to make sure the structure of the data is correct, but not get worried about the encoding.
[...]
Quoted 20 lines
Quoted 11 lines
Quoted 11 lines
Documentation/devicetree/bindings/example-schema.yaml new file +11
-0+ interrupts: + # Either 1 or 2 interrupts can be present + minItems: 1 + maxItems: 2 + items: + - description: tx or combined interrupt + - description: rx interrupt + + description: | + A variable number of interrupts warrants a description of what conditions + affect the number of interrupts. Otherwise, descriptions on standardQuoted 8 lines
Documentation/devicetree/bindings/example-schema.yaml line 98
Quoted 5 lines
Documentation/devicetree/bindings/example-schema.yaml new file +5
-0+ properties are not necessary. + + interrupt-names: + # minItems must be specified here because the default would be 2 + minItems: 1Why the difference between the interrupts property and the interrupt-names property (specifying maxItems for interrupt, but not interrupt-names)?
Quoted 8 lines
I should probably have maxItems here too.
Quoted 2 lines
Others have already commented on a desire to have a way to specify that number of interrupts should match number of interrupt-names.
Yeah, but I don't see a way to do that. You could stick the array size constraints in a common definition and have a $ref to that definition from both, but that doesn't really save you too much.
There has been discussions in the jsonschema community regarding referencing data in the document when applying the schema.
https://github.com/json-schema-org/json-schema-spec/issues/549
However, those discussions are ongoing and have been pushed back to after draft-8 (the current release is draft-7). We can instead define DT-specific keywords and extend the validator to make it do what we want. We need to do something very similar to validate that the length of tuples in 'reg', 'interrupts', and '*gpios' match the '#*-cells' values.
IMPORTANT NOTICE: The contents of this email and any attachments are confidential and may also be privileged. If you are not the intended recipient, please notify the sender immediately and do not disclose the contents to any other person, use it for any purpose, or store or copy the information in any medium. Thank you.
Hi Grant,
Quoted 39 lines · Grant Likely
Quoted 25 lines · Rob Herring
Quoted 14 lines · Frank Rowand
Quoted 14 lines
Documentation/devicetree/bindings/example-schema.yaml new file +10
-0+ interrupts: + # Either 1 or 2 interrupts can be present + minItems: 1 + maxItems: 2 + items: + - description: tx or combined interrupt + - description: rx interrupt + + description: | + A variable number of interrupts warrants a description of whatconditions
+ affect the number of interrupts. Otherwise, descriptions on
standard
+ properties are not necessary.Quoted 8 lines
Documentation/devicetree/bindings/example-schema.yaml line 98
Quoted 4 lines
Documentation/devicetree/bindings/example-schema.yaml new file +4
-0+ + interrupt-names: + # minItems must be specified here because the default would be 2 + minItems: 1Why the difference between the interrupts property and the interrupt-names
property (specifying maxItems for interrupt, but not interrupt-names)?Quoted 8 lines
I should probably have maxItems here too.
Quoted 2 lines
Others have already commented on a desire to have a way to specify that number of interrupts should match number of interrupt-names.
Yeah, but I don't see a way to do that. You could stick the array size constraints in a common definition and have a $ref to that definition from both, but that doesn't really save you too much.
There has been discussions in the jsonschema community regarding referencing data in the document when applying the schema.
Quoted 7 lines
https://github.com/json-schema-org/json-schema-spec/issues/549
However, those discussions are ongoing and have been pushed back to after draft-8 (the current release is draft-7). We can instead define DT-specific keywords and extend the validator to make it do what we want. We need to do something very similar to validate that the length of tuples in 'reg', 'interrupts', and '*gpios' match the '#*-cells' values.
Checking that property lengths match the corresponding #*-cells cannot be done for a schema, but only for the final DTS, as #*-cells is a property of the target node, right?
Gr{oetje,eeting}s,
Geert
Signature · 5 lines
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- [email protected] In personal conversations with technical people, I call myself a hacker. But when I'm talking to journalists I just say "programmer" or something like that. -- Linus Torvalds
Quoted 50 lines · Geert Uytterhoeven
Hi Grant,
Quoted 39 lines · Grant Likely
Quoted 25 lines · Rob Herring
Quoted 14 lines · Frank Rowand
Quoted 14 lines
Documentation/devicetree/bindings/example-schema.yaml new file +10
-0+ interrupts: + # Either 1 or 2 interrupts can be present + minItems: 1 + maxItems: 2 + items: + - description: tx or combined interrupt + - description: rx interrupt + + description: | + A variable number of interrupts warrants a description of whatconditions
+ affect the number of interrupts. Otherwise, descriptions on
standard
+ properties are not necessary.Quoted 8 lines
Documentation/devicetree/bindings/example-schema.yaml line 98
Quoted 4 lines
Documentation/devicetree/bindings/example-schema.yaml new file +4
-0+ + interrupt-names: + # minItems must be specified here because the default would be 2 + minItems: 1Why the difference between the interrupts property and the interrupt-names
property (specifying maxItems for interrupt, but not interrupt-names)?Quoted 8 lines
I should probably have maxItems here too.
Quoted 2 lines
Others have already commented on a desire to have a way to specify that number of interrupts should match number of interrupt-names.
Yeah, but I don't see a way to do that. You could stick the array size constraints in a common definition and have a $ref to that definition from both, but that doesn't really save you too much.
There has been discussions in the jsonschema community regarding referencing data in the document when applying the schema.
Quoted 7 lines
https://github.com/json-schema-org/json-schema-spec/issues/549
However, those discussions are ongoing and have been pushed back to after draft-8 (the current release is draft-7). We can instead define DT-specific keywords and extend the validator to make it do what we want. We need to do something very similar to validate that the length of tuples in 'reg', 'interrupts', and '*gpios' match the '#*-cells' values.
Quoted 3 lines
Checking that property lengths match the corresponding #*-cells cannot be done for a schema, but only for the final DTS, as #*-cells is a property of the target node, right?
It can be done in the schema checking of the target node. For example, given a GPIO specifier of:
gpios = <&gpio1 0> <&gpio2 4 1> <&gpio2 3 0>;
The validation engine could validate that the &gpio1 and &gpio2 targets have the same length as the associated gpio descriptor tuples. (ex. gpio1 needs #gpio-cells=<1>; and gpio2 needs #gpio-cells=<2>; If the tuples are the wrong size, then validation should fail.
g.
Quoted 5 lines
Gr{oetje,eeting}s,
Geert
IMPORTANT NOTICE: The contents of this email and any attachments are confidential and may also be privileged. If you are not the intended recipient, please notify the sender immediately and do not disclose the contents to any other person, use it for any purpose, or store or copy the information in any medium. Thank you.
Quoted 48 lines · Rob Herring
Quoted 37 lines · Frank Rowand
Hi Rob,
Thanks for the example. It was a good starting tutorial of sorts for me to understand the format a bit.
Quoted 30 lines · Rob Herring
The current DT binding documentation format of freeform text is painful to write, review, validate and maintain.
This is just an example of what a binding in the schema format looks like. It's using jsonschema vocabulary in a YAML encoded document. Using jsonschema gives us access to existing tooling. A YAML encoding gives us something easy to edit.
This example is just the tip of the iceberg, but it the part most developers writing bindings will interact with. Backing all this up are meta-schema (to validate the binding schemas), some DT core schema, YAML encoded DT output with dtc, and a small number of python scripts to run validation. The gory details including how to run end-to-end validation can be found here:
https://www.spinics.net/lists/devicetree-spec/msg00649.html
Signed-off-by Rob Herring <[email protected]>---
Cc list,
You all review and/or write lots of binding documents. I'd like some feedback on the format.Thanks,
Rob.../devicetree/bindings/example-schema.yaml | 149 +++++++++++++++++++++ 1 file changed, 149 insertions(+) create mode 100644 Documentation/devicetree/bindings/example-schema.yamlQuoted 7 lines
Documentation/devicetree/bindings/example-schema.yaml
Quoted 5 lines
Documentation/devicetree/bindings/example-schema.yaml new file +0
-0I'm guessing by the path name that this is in the Linux kernel source tree.
Yes, well, my kernel tree. Most of the work still lives here:
Quoted 8 lines
https://github.com/robherring/yaml-bindings/
Quoted 4 lines
Documentation/devicetree/bindings/example-schema.yaml line 1
Quoted 2 lines
Documentation/devicetree/bindings/example-schema.yaml new file +1
-0@@ -0,0 +1,149 @@ +# SPDX-License-Identifier: BSD-2-ClauseIf in the Linux kernel source tree, then allow gpl-v2 as a possible license.
Why? BSD is compatible. The license of the above repo is all BSD.
I said __if__ in the Linux kernel source tree. As my other comments indicated, I wasn't sure if this was intended to end up in the Linux kernel source tree. __If__ in the Linux kernel source tree then it would be dual licensed, correct? And thus the tag would reflect that?
Quoted 3 lines
Of course there's all the existing docs which default to GPLv2 and we'll probably have to maintain that.
< snip >
Quoted 7 lines · Rob Herring
I share the concern as I doubt most kernel developers don't know jsonschema. But then the alternative is us defining and writing our own thing which is C like 'cause that's what kernel developers understand. My hope is to simplify and restrict things enough that it writing a binding doc is straightforward without being jsonschema experts. That was the intent of this patch without going into all the details behind it.
When schemas were first discussed long, long ago the idea was to have a n arbitrator who controls the schema (like Grant/Rob) so there is no need for general schema design knowledge in random kernel developers.
First a developer should try and build their device tree using the existing schema. Then only if they find that impossible to do so should they propose schema changes. The schema arbitrator would then look at those changes and work them into the existing schemas as needed. Doing this via an arbitrator will ensure consistency in the overall schema design while eliminating redundancy with slight variations (like we have now).
Another side effect of schemas is that as they evolve and enforce commonality among driver implementation it will become possible to turn those in-common pieces into driver libraries.
Signature · 2 lines
Jon Smirl [email protected]
Rob Herring
maintainerQuoted 22 lines · On Wed, Nov 14, 2018 at 1:39 PM [email protected] <[email protected]> wrote:
Quoted 7 lines · Rob Herring
I share the concern as I doubt most kernel developers don't know jsonschema. But then the alternative is us defining and writing our own thing which is C like 'cause that's what kernel developers understand. My hope is to simplify and restrict things enough that it writing a binding doc is straightforward without being jsonschema experts. That was the intent of this patch without going into all the details behind it.
When schemas were first discussed long, long ago the idea was to have a n arbitrator who controls the schema (like Grant/Rob) so there is no need for general schema design knowledge in random kernel developers.
First a developer should try and build their device tree using the existing schema. Then only if they find that impossible to do so should they propose schema changes. The schema arbitrator would then look at those changes and work them into the existing schemas as needed. Doing this via an arbitrator will ensure consistency in the overall schema design while eliminating redundancy with slight variations (like we have now).
Quoted 3 lines
Another side effect of schemas is that as they evolve and enforce commonality among driver implementation it will become possible to turn those in-common pieces into driver libraries.
If we replace 'schemas' everywhere above with 'bindings', then this pretty much describes the status quo today. Most device specific bindings are a collection of standard bindings. Occasionally, we have new common bindings. All the bindings get reviewed by me. The only real change here is submitters have to have some level of understanding of json-schema instead of just English (for writing free form text). I think it will continue to largely be following existing examples of other bindings.
Rob
Quoted 28 lines · Rob Herring
Quoted 22 lines · On Wed, Nov 14, 2018 at 1:39 PM [email protected] <[email protected]> wrote:
Quoted 7 lines · Rob Herring
I share the concern as I doubt most kernel developers don't know jsonschema. But then the alternative is us defining and writing our own thing which is C like 'cause that's what kernel developers understand. My hope is to simplify and restrict things enough that it writing a binding doc is straightforward without being jsonschema experts. That was the intent of this patch without going into all the details behind it.
When schemas were first discussed long, long ago the idea was to have a n arbitrator who controls the schema (like Grant/Rob) so there is no need for general schema design knowledge in random kernel developers.
First a developer should try and build their device tree using the existing schema. Then only if they find that impossible to do so should they propose schema changes. The schema arbitrator would then look at those changes and work them into the existing schemas as needed. Doing this via an arbitrator will ensure consistency in the overall schema design while eliminating redundancy with slight variations (like we have now).
Quoted 3 lines
Another side effect of schemas is that as they evolve and enforce commonality among driver implementation it will become possible to turn those in-common pieces into driver libraries.
Quoted 8 lines
If we replace 'schemas' everywhere above with 'bindings', then this pretty much describes the status quo today. Most device specific bindings are a collection of standard bindings. Occasionally, we have new common bindings. All the bindings get reviewed by me. The only real change here is submitters have to have some level of understanding of json-schema instead of just English (for writing free form text). I think it will continue to largely be following existing examples of other bindings.
What used to happen is that drivers would be written out of tree without review of their bindings until mainline submission (if they submit them at all). With schema a driver writer who is working out of tree can use the schema to validate their new device tree entries before submitting them. That way they will know ahead of time if they are making up something non-standard. It will also give them the heads up that they can't just make up anything they want in the device tree and that they are going to have to defend their design when asking for the schema to be changed to support it. An example of where schema would have been initially valuable is in the i2c bindings which contain significant variation but the function is the same.
Maybe we are thinking about schema differently. I had envisioned starting from a base generic schema that is capable of validating all possible legal Linux device trees. This schema is more strict that YAML syntax, but it obviously can't validate in detail. Someone working out of tree would always be able to validate against this schema.
As this generic schema validates the device tree it will discover that it can utilize more strict schema fragments. So by providing these fragments you can validate to any desired level of conformance. The end of that process is the json-schema bindings file. But if those fragments are missing you can still validate, just not at a detailed level.
A large set of schemas that work like this are used in ONVIF (security cameras). A flavor of SOAP.
https://www.onvif.org/profiles/specifications/
These schemas are using XML stylesheets to make them pretty, use view source to see the actual schemas.
The ONVIF schemas define points where vendors are allowed to insert arbitrary items (ANY elements) and then they will use a vendor supplied schema to validate the fragment if one is available. If not the generic schema is used to validate the basic structure of the vendor fragments.
Quoted 2 lines
Rob
Signature · 2 lines
Jon Smirl [email protected]
Quoted 15 lines · Rob Herring
The current DT binding documentation format of freeform text is painful to write, review, validate and maintain.
This is just an example of what a binding in the schema format looks like. It's using jsonschema vocabulary in a YAML encoded document. Using jsonschema gives us access to existing tooling. A YAML encoding gives us something easy to edit.
This example is just the tip of the iceberg, but it the part most developers writing bindings will interact with. Backing all this up are meta-schema (to validate the binding schemas), some DT core schema, YAML encoded DT output with dtc, and a small number of python scripts to run validation. The gory details including how to run end-to-end validation can be found here:
Quoted 8 lines
https://www.spinics.net/lists/devicetree-spec/msg00649.html
Signed-off-by Rob Herring <[email protected]>---
Cc list,
You all review and/or write lots of binding documents. I'd like some feedback on the format.
I really like the idea of formalizing the binding document format and the ability of validating a dtb is really nice.
Quoted 8 lines
Thanks,
Rob.../devicetree/bindings/example-schema.yaml | 149 +++++++++++++++++++++ 1 file changed, 149 insertions(+) create mode 100644 Documentation/devicetree/bindings/example-schema.yamlDocumentation/devicetree/bindings/example-schema.yaml +0
-0
[..]
Documentation/devicetree/bindings/example-schema.yaml line 67
Quoted 7 lines
Documentation/devicetree/bindings/example-schema.yaml +7
-0+ reg: + # The description of each element defines the order and implicitly defines + # the number of reg entries + items: + - description: core registers + - description: aux registers + # minItems/maxItems equal to 2 is implied
I assume that a reg with variable number of entries would have "description" for all of them and then a minItems that matches the required ones and maxItems matching all of them?
Documentation/devicetree/bindings/example-schema.yaml line 73
Quoted 6 lines
Documentation/devicetree/bindings/example-schema.yaml +6
-0+ + reg-names: + # The core schema enforces this is a string array + items: + - const: core + - const: aux
I presume validation based on this should check that there's equal number of entries in reg-names as there where in reg. Should this relationship be described in the schema?
[..]
Documentation/devicetree/bindings/example-schema.yaml line 94
Quoted 12 lines
Documentation/devicetree/bindings/example-schema.yaml +12
-0+ interrupts: + # Either 1 or 2 interrupts can be present + minItems: 1 + maxItems: 2 + items: + - description: tx or combined interrupt + - description: rx interrupt + + description: | + A variable number of interrupts warrants a description of what conditions + affect the number of interrupts. Otherwise, descriptions on standard + properties are not necessary.
For validation purposes this could be interrupts with interrupt-parents or a interrupts-extend, a fact that we probably don't want to duplicate in every definition?
Perhaps we should just do like you did here and define the "interrupts" and then in the validation tool - where we need to encode the logic behind this anyways - we support the different variants.
Documentation/devicetree/bindings/example-schema.yaml line 98
Quoted 4 lines
Documentation/devicetree/bindings/example-schema.yaml +4
-0+ + interrupt-names: + # minItems must be specified here because the default would be 2 + minItems: 1
As with reg-names, it would be good to have the validator warn if this is not the same number of items as entries in "interrupts".
Documentation/devicetree/bindings/example-schema.yaml line 107
Quoted 9 lines
Documentation/devicetree/bindings/example-schema.yaml +9
-0+ items: + - const: "tx irq" + - const: "rx irq" + + # Property names starting with '#' must be quoted + '#interrupt-cells': + # A simple case where the value must always be '2'. + # The core schema handles that this must be a single integer. + const: 2
If this is specified then interrupt-controller should also be given, or vise versa. How would we describe that?
Documentation/devicetree/bindings/example-schema.yaml line 112
Quoted 5 lines
Documentation/devicetree/bindings/example-schema.yaml +5
-0+ + interrupt-controller: {} + # The core checks this is a boolean, so just have to list it here to be + # valid for this binding. +
Regards,
Bjorn
Rob Herring
maintainerQuoted 46 lines · Bjorn Andersson
Quoted 15 lines · Rob Herring
The current DT binding documentation format of freeform text is painful to write, review, validate and maintain.
This is just an example of what a binding in the schema format looks like. It's using jsonschema vocabulary in a YAML encoded document. Using jsonschema gives us access to existing tooling. A YAML encoding gives us something easy to edit.
This example is just the tip of the iceberg, but it the part most developers writing bindings will interact with. Backing all this up are meta-schema (to validate the binding schemas), some DT core schema, YAML encoded DT output with dtc, and a small number of python scripts to run validation. The gory details including how to run end-to-end validation can be found here:
Quoted 8 lines
https://www.spinics.net/lists/devicetree-spec/msg00649.html
Signed-off-by Rob Herring <[email protected]>---
Cc list,
You all review and/or write lots of binding documents. I'd like some feedback on the format.I really like the idea of formalizing the binding document format and the ability of validating a dtb is really nice.
Quoted 8 lines
Thanks,
Rob.../devicetree/bindings/example-schema.yaml | 149 +++++++++++++++++++++ 1 file changed, 149 insertions(+) create mode 100644 Documentation/devicetree/bindings/example-schema.yamlDocumentation/devicetree/bindings/example-schema.yaml +0
-0[..]
Documentation/devicetree/bindings/example-schema.yaml line 67
Quoted 7 lines
Documentation/devicetree/bindings/example-schema.yaml +7
-0+ reg: + # The description of each element defines the order and implicitly defines + # the number of reg entries + items: + - description: core registers + - description: aux registers + # minItems/maxItems equal to 2 is implied
Quoted 3 lines
I assume that a reg with variable number of entries would have "description" for all of them and then a minItems that matches the required ones and maxItems matching all of them?
You could do that, but it doesn't really enforce which compatible(s) each size of reg is valid for. It would work okay when just the last N entries are variable, but it will break down if you have cases where essentially any subset is valid. For bindings with lots of conditional sizes for reg, clocks, resets, etc. based on compatible strings, I think we will need to split the binding into a schema per compatible.
IMO, things like this are probably not going to be addressed at the start and may remain in the description (as we have today). I think we need to start with a base schema and can improve them over time.
Quoted 10 lines
Documentation/devicetree/bindings/example-schema.yaml line 73
Quoted 6 lines
Documentation/devicetree/bindings/example-schema.yaml +6
-0+ + reg-names: + # The core schema enforces this is a string array + items: + - const: core + - const: auxI presume validation based on this should check that there's equal number of entries in reg-names as there where in reg. Should this relationship be described in the schema?
Yes, if we can figure out how. But I don't think it belongs in per device schema as it is a core requirement.
Quoted 15 lines
[..]
Documentation/devicetree/bindings/example-schema.yaml line 94
Quoted 12 lines
Documentation/devicetree/bindings/example-schema.yaml +12
-0+ interrupts: + # Either 1 or 2 interrupts can be present + minItems: 1 + maxItems: 2 + items: + - description: tx or combined interrupt + - description: rx interrupt + + description: | + A variable number of interrupts warrants a description of what conditions + affect the number of interrupts. Otherwise, descriptions on standard + properties are not necessary.
Quoted 7 lines
For validation purposes this could be interrupts with interrupt-parents or a interrupts-extend, a fact that we probably don't want to duplicate in every definition?
Perhaps we should just do like you did here and define the "interrupts" and then in the validation tool - where we need to encode the logic behind this anyways - we support the different variants.
Yes, essentially as we do now where the binding just describes 'interrupts' and 'interrupts-extended' is implicitly supported.
Quoted 18 lines
Documentation/devicetree/bindings/example-schema.yaml line 98
Quoted 4 lines
Documentation/devicetree/bindings/example-schema.yaml +4
-0+ + interrupt-names: + # minItems must be specified here because the default would be 2 + minItems: 1As with reg-names, it would be good to have the validator warn if this is not the same number of items as entries in "interrupts".
Documentation/devicetree/bindings/example-schema.yaml line 107
Quoted 9 lines
Documentation/devicetree/bindings/example-schema.yaml +9
-0+ items: + - const: "tx irq" + - const: "rx irq" + + # Property names starting with '#' must be quoted + '#interrupt-cells': + # A simple case where the value must always be '2'. + # The core schema handles that this must be a single integer. + const: 2
Quoted 2 lines
If this is specified then interrupt-controller should also be given, or vise versa. How would we describe that?
The core meta-schema can check that with 'dependencies'. Here's gpio meta-schema for example:
dependencies:
gpio-controller: ['#gpio-cells']
'#gpio-cells': [gpio-controller]
gpio-ranges: [gpio-controller]
ngpios: [gpio-controller]
Rob