zephyr/scripts/dts/test.dts

431 lines
8.2 KiB
Text
Raw Normal View History

dts: Add new DTS/binding parser Add a new DTS/binding parser to scripts/dts/ for generating generated_dts_board.conf and generated_dts_board_unfixed.h. The old code is kept to generate some deprecated defines, using the --deprecated-only flag. It will be removed later. The new parser is implemented in three files in scripts/dts/: dtlib.py: A low-level .dts parsing library. This is similar to devicetree.py in the old code, but is a general robust DTS parser that doesn't rely on preprocessing. edtlib.py (e for extended): A library built on top of dtlib.py that brings together data from DTS files and bindings and creates Device instances with all the data for a device. gen_defines.py: A script that uses edtlib.py to generate generated_dts_board.conf and generated_dts_board_unfixed.h. Corresponds to extract_dts_includes.py and the files in extract/ in the old code. testdtlib.py: Test suite for dtlib.py. Can be run directly as a script. testedtlib.py (uses test.dts and test-bindings/): Test suite for edtlib.py. Can be run directly as a script. The test suites will be run automatically in CI. The new code turns some things that were warnings (or not checked) in the old code into errors, like missing properties that are specified with 'category: required' in the binding for the node. The code includes lots of documentation and tries to give helpful error messages instead of Python errors. Co-authored-by: Kumar Gala <kumar.gala@linaro.org> Signed-off-by: Ulf Magnusson <Ulf.Magnusson@nordicsemi.no>
2018-12-17 20:09:47 +01:00
/*
* Copyright (c) 2019, Nordic Semiconductor
*
* SPDX-License-Identifier: BSD-3-Clause
*/
// Used by testedtlib.py
/dts-v1/;
/ {
//
// Interrupts
//
interrupt-parent-test {
controller {
compatible = "interrupt-three-cell";
#interrupt-cells = <3>;
interrupt-controller;
};
node {
interrupts = <1 2 3 4 5 6>;
interrupt-names = "foo", "bar";
interrupt-parent = <&{/interrupt-parent-test/controller}>;
};
};
interrupts-extended-test {
controller-0 {
compatible = "interrupt-one-cell";
#interrupt-cells = <1>;
interrupt-controller;
};
controller-1 {
compatible = "interrupt-two-cell";
#interrupt-cells = <2>;
interrupt-controller;
};
controller-2 {
compatible = "interrupt-three-cell";
#interrupt-cells = <3>;
interrupt-controller;
};
node {
interrupts-extended = <
&{/interrupts-extended-test/controller-0} 1
&{/interrupts-extended-test/controller-1} 2 3
&{/interrupts-extended-test/controller-2} 4 5 6>;
};
};
interrupt-map-test {
#address-cells = <2>;
#size-cells = <0>;
controller-0 {
compatible = "interrupt-one-cell";
#address-cells = <1>;
#interrupt-cells = <1>;
interrupt-controller;
};
controller-1 {
compatible = "interrupt-two-cell";
#address-cells = <2>;
#interrupt-cells = <2>;
interrupt-controller;
};
controller-2 {
compatible = "interrupt-three-cell";
#address-cells = <3>;
#interrupt-cells = <3>;
interrupt-controller;
};
nexus {
#interrupt-cells = <2>;
interrupt-map = <
0 0 0 0 &{/interrupt-map-test/controller-0} 0 0
0 0 0 1 &{/interrupt-map-test/controller-1} 0 0 0 1
0 0 0 2 &{/interrupt-map-test/controller-2} 0 0 0 0 0 2
0 1 0 0 &{/interrupt-map-test/controller-0} 0 3
0 1 0 1 &{/interrupt-map-test/controller-1} 0 0 0 4
0 1 0 2 &{/interrupt-map-test/controller-2} 0 0 0 0 0 5>;
};
node@0 {
reg = <0 0>;
interrupts = <0 0 0 1 0 2>;
interrupt-parent = <&{/interrupt-map-test/nexus}>;
};
node@1 {
reg = <0 1>;
interrupts-extended = <
&{/interrupt-map-test/nexus} 0 0
&{/interrupt-map-test/nexus} 0 1
&{/interrupt-map-test/nexus} 0 2>;
};
};
interrupt-map-bitops-test {
#address-cells = <2>;
#size-cells = <0>;
controller {
compatible = "interrupt-two-cell";
#address-cells = <0>;
#interrupt-cells = <2>;
interrupt-controller;
};
nexus {
#interrupt-cells = <2>;
interrupt-map = <
6 6 6 6 &{/interrupt-map-bitops-test/controller} 2 1
>;
interrupt-map-mask = <0xE 0x7 0xE 0x7>;
// Not specified in the DT spec., but shows up due to
// common code with GPIO. Might as well test it here.
interrupt-map-pass-thru = <1 2 3 3>;
};
// Child unit specifier: 00000007 0000000E 00000007 0000000E
// Mask: 0000000E 00000007 0000000E 00000007
// Pass-thru: 00000001 00000002 00000003 00000003
node@70000000E {
reg = <0x7 0xE>;
interrupt-parent = <&{/interrupt-map-bitops-test/nexus}>;
interrupts = <0x7 0xE>;
};
};
//
// 'reg'
//
reg-zero-address-cells {
#address-cells = <0>;
#size-cells = <1>;
node {
reg = <1 2>;
};
};
reg-zero-size-cells {
#address-cells = <1>;
#size-cells = <0>;
node {
reg = <1 2>;
};
};
// Use implied #size-cells = <1>
reg-ranges {
#address-cells = <2>;
parent {
#address-cells = <1>;
ranges = <1 0xA 0xB 1 /* 1 -> 0xA 0xB */
2 0xC 0xD 2 /* 2..3 -> 0xC 0xD */
4 0xE 0xF 1 /* 4 -> 0xE 0xF */
>;
node {
reg = <5 1 /* Matches no range */
4 1 /* Matches third range */
3 1 /* Matches second range */
2 1 /* Matches second range */
1 1 /* Matches first range */
0 1 /* Matches no range */
>;
};
};
};
// Build up <3 2 1> address with nested 'ranges'
reg-nested-ranges {
#address-cells = <3>;
grandparent {
#address-cells = <2>;
#size-cells = <2>;
ranges = <0 0 3 0 0 2 2>;
parent {
#address-cells = <1>;
ranges = <0 2 0 2>;
node {
reg = <1 1>;
};
};
};
};
//
// 'pinctrl-<index>'
//
pinctrl {
dev {
pinctrl-0 = <>;
pinctrl-1 = <&{/pinctrl/pincontroller/state-1}>;
pinctrl-2 = <&{/pinctrl/pincontroller/state-1}
&{/pinctrl/pincontroller/state-2}>;
pinctrl-names = "zero", "one", "two";
};
pincontroller {
state-1 {
};
state-2 {
};
};
};
//
scripts: dts: Generalize handling of phandle-array types Generating generic information for 'type: phandle-array' properties in edtlib was difficult due to defining phandle-array as just a list of phandles and numbers. To make sense of a phandle-array property like 'pwms', you have to know that #pwm-cells is expected to appear on each referenced controller, and that the binding for the controller has a #cells. Because of this, handling of various 'type: phandle-array' properties was previously hardcoded in edtlib and exposed through properties like Node.pwms, instead of through the generic Node.props (though with a lot of shared code). In practice, it turns out that all 'type: phandle-array' properties in Zephyr work exactly the same way: They all have names that end in -s, the 's' is removed to derive the name of related properties, and they all look up #cells in the binding for the controller, which gives names to the data values. Strengthen the definition of 'type: phandle-array' to mean a property that works exactly like the existing phandle-array properties (which also means requiring that the name ends in -s). This removes a ton of hardcoding from edtlib and allows new 'type: phandle-array' properties to be added without making any code changes. If we ever need a property type that's a list of phandles and numbers but that doesn't follow this scheme, then we could add a separate type for it. We should check if the standard scheme is fine first though. The only property type for which no information is generated is now 'compound'. There's some inconsistency in how we generate identifiers for clocks compared to other 'type: phandle-array' properties, so keep special-casing them for now in gen_defines.py (see the comment in write_clocks()). This change also enabled a bunch of other simplifications, like reusing the ControllerAndData class for interrupts. Piggyback generalization of *-map properties so that they work for any phandle-array properties. It's now possible to have things like 'io-channel-map', if you need to. Signed-off-by: Ulf Magnusson <Ulf.Magnusson@nordicsemi.no>
2019-09-23 09:10:22 +02:00
// For testing Node.parent and Node.children
//
parent {
child-1 {
};
child-2 {
grandchild {
};
};
};
dts: Add new DTS/binding parser Add a new DTS/binding parser to scripts/dts/ for generating generated_dts_board.conf and generated_dts_board_unfixed.h. The old code is kept to generate some deprecated defines, using the --deprecated-only flag. It will be removed later. The new parser is implemented in three files in scripts/dts/: dtlib.py: A low-level .dts parsing library. This is similar to devicetree.py in the old code, but is a general robust DTS parser that doesn't rely on preprocessing. edtlib.py (e for extended): A library built on top of dtlib.py that brings together data from DTS files and bindings and creates Device instances with all the data for a device. gen_defines.py: A script that uses edtlib.py to generate generated_dts_board.conf and generated_dts_board_unfixed.h. Corresponds to extract_dts_includes.py and the files in extract/ in the old code. testdtlib.py: Test suite for dtlib.py. Can be run directly as a script. testedtlib.py (uses test.dts and test-bindings/): Test suite for edtlib.py. Can be run directly as a script. The test suites will be run automatically in CI. The new code turns some things that were warnings (or not checked) in the old code into errors, like missing properties that are specified with 'category: required' in the binding for the node. The code includes lots of documentation and tries to give helpful error messages instead of Python errors. Co-authored-by: Kumar Gala <kumar.gala@linaro.org> Signed-off-by: Ulf Magnusson <Ulf.Magnusson@nordicsemi.no>
2018-12-17 20:09:47 +01:00
//
// For testing 'include:'
dts: Add new DTS/binding parser Add a new DTS/binding parser to scripts/dts/ for generating generated_dts_board.conf and generated_dts_board_unfixed.h. The old code is kept to generate some deprecated defines, using the --deprecated-only flag. It will be removed later. The new parser is implemented in three files in scripts/dts/: dtlib.py: A low-level .dts parsing library. This is similar to devicetree.py in the old code, but is a general robust DTS parser that doesn't rely on preprocessing. edtlib.py (e for extended): A library built on top of dtlib.py that brings together data from DTS files and bindings and creates Device instances with all the data for a device. gen_defines.py: A script that uses edtlib.py to generate generated_dts_board.conf and generated_dts_board_unfixed.h. Corresponds to extract_dts_includes.py and the files in extract/ in the old code. testdtlib.py: Test suite for dtlib.py. Can be run directly as a script. testedtlib.py (uses test.dts and test-bindings/): Test suite for edtlib.py. Can be run directly as a script. The test suites will be run automatically in CI. The new code turns some things that were warnings (or not checked) in the old code into errors, like missing properties that are specified with 'category: required' in the binding for the node. The code includes lots of documentation and tries to give helpful error messages instead of Python errors. Co-authored-by: Kumar Gala <kumar.gala@linaro.org> Signed-off-by: Ulf Magnusson <Ulf.Magnusson@nordicsemi.no>
2018-12-17 20:09:47 +01:00
//
binding-include {
compatible = "binding-include-test";
foo = <0>;
bar = <1>;
baz = <2>;
qaz = <3>;
dts: Add new DTS/binding parser Add a new DTS/binding parser to scripts/dts/ for generating generated_dts_board.conf and generated_dts_board_unfixed.h. The old code is kept to generate some deprecated defines, using the --deprecated-only flag. It will be removed later. The new parser is implemented in three files in scripts/dts/: dtlib.py: A low-level .dts parsing library. This is similar to devicetree.py in the old code, but is a general robust DTS parser that doesn't rely on preprocessing. edtlib.py (e for extended): A library built on top of dtlib.py that brings together data from DTS files and bindings and creates Device instances with all the data for a device. gen_defines.py: A script that uses edtlib.py to generate generated_dts_board.conf and generated_dts_board_unfixed.h. Corresponds to extract_dts_includes.py and the files in extract/ in the old code. testdtlib.py: Test suite for dtlib.py. Can be run directly as a script. testedtlib.py (uses test.dts and test-bindings/): Test suite for edtlib.py. Can be run directly as a script. The test suites will be run automatically in CI. The new code turns some things that were warnings (or not checked) in the old code into errors, like missing properties that are specified with 'category: required' in the binding for the node. The code includes lots of documentation and tries to give helpful error messages instead of Python errors. Co-authored-by: Kumar Gala <kumar.gala@linaro.org> Signed-off-by: Ulf Magnusson <Ulf.Magnusson@nordicsemi.no>
2018-12-17 20:09:47 +01:00
};
//
scripts: dts: Generalize handling of phandle-array types Generating generic information for 'type: phandle-array' properties in edtlib was difficult due to defining phandle-array as just a list of phandles and numbers. To make sense of a phandle-array property like 'pwms', you have to know that #pwm-cells is expected to appear on each referenced controller, and that the binding for the controller has a #cells. Because of this, handling of various 'type: phandle-array' properties was previously hardcoded in edtlib and exposed through properties like Node.pwms, instead of through the generic Node.props (though with a lot of shared code). In practice, it turns out that all 'type: phandle-array' properties in Zephyr work exactly the same way: They all have names that end in -s, the 's' is removed to derive the name of related properties, and they all look up #cells in the binding for the controller, which gives names to the data values. Strengthen the definition of 'type: phandle-array' to mean a property that works exactly like the existing phandle-array properties (which also means requiring that the name ends in -s). This removes a ton of hardcoding from edtlib and allows new 'type: phandle-array' properties to be added without making any code changes. If we ever need a property type that's a list of phandles and numbers but that doesn't follow this scheme, then we could add a separate type for it. We should check if the standard scheme is fine first though. The only property type for which no information is generated is now 'compound'. There's some inconsistency in how we generate identifiers for clocks compared to other 'type: phandle-array' properties, so keep special-casing them for now in gen_defines.py (see the comment in write_clocks()). This change also enabled a bunch of other simplifications, like reusing the ControllerAndData class for interrupts. Piggyback generalization of *-map properties so that they work for any phandle-array properties. It's now possible to have things like 'io-channel-map', if you need to. Signed-off-by: Ulf Magnusson <Ulf.Magnusson@nordicsemi.no>
2019-09-23 09:10:22 +02:00
// For testing Node.props (derived from 'properties:' in the binding)
dts: Add new DTS/binding parser Add a new DTS/binding parser to scripts/dts/ for generating generated_dts_board.conf and generated_dts_board_unfixed.h. The old code is kept to generate some deprecated defines, using the --deprecated-only flag. It will be removed later. The new parser is implemented in three files in scripts/dts/: dtlib.py: A low-level .dts parsing library. This is similar to devicetree.py in the old code, but is a general robust DTS parser that doesn't rely on preprocessing. edtlib.py (e for extended): A library built on top of dtlib.py that brings together data from DTS files and bindings and creates Device instances with all the data for a device. gen_defines.py: A script that uses edtlib.py to generate generated_dts_board.conf and generated_dts_board_unfixed.h. Corresponds to extract_dts_includes.py and the files in extract/ in the old code. testdtlib.py: Test suite for dtlib.py. Can be run directly as a script. testedtlib.py (uses test.dts and test-bindings/): Test suite for edtlib.py. Can be run directly as a script. The test suites will be run automatically in CI. The new code turns some things that were warnings (or not checked) in the old code into errors, like missing properties that are specified with 'category: required' in the binding for the node. The code includes lots of documentation and tries to give helpful error messages instead of Python errors. Co-authored-by: Kumar Gala <kumar.gala@linaro.org> Signed-off-by: Ulf Magnusson <Ulf.Magnusson@nordicsemi.no>
2018-12-17 20:09:47 +01:00
//
props {
compatible = "props";
dts: dtlib/edtlib: Add a syntax-based type-checking system Property type-checking has been pretty rudimentary until now, only checking things like the length being divisible by 4 for 'type: array', and strings being null-terminated. In particular, no checking was done for 'type: uint8-array', letting jedec-id = < 0xc8 0x28 0x17 >; slip through when jedec-id = [ 0xc8 0x28 0x17 ]; was intended. Fix it by adding a syntax-based type checker: 1. Add Property.type, which gives a high-level type for the property, derived from the markers added in the previous commit. This includes types like TYPE_EMPTY ('foo;'), TYPE_NUM ('foo = < 3 >;'), TYPE_BYTES ('foo = [ 01 02 ];'), TYPE_STRINGS ('foo = "bar", "baz"'), TYPE_PHANDLE ('foo = < &bar >;'), and TYPE_COMPOUND (everything not recognized). See the Property.type docstring in dtlib for more info. 2. Use the high-level type in Property.to_num()/to_string()/to_node()/etc. to verify that the property was assigned in an expected way for the type. If the assignment looks bad, give a helpful error: expected property 'nums' on /foo/bar in some.dts to be assigned with 'nums = < (number) (number) ... >', not 'nums = "oops";' Some other related changes are included as well: - There's a new Property.to_bytes() function that works like accessing Property.bytes, except with an added check for the value being assigned like 'foo = [ ... ]'. This function solves problems like the jedec-id one. - There's a new Property.to_path() function for fetching the referenced node for assignments like 'foo = &node;', with type checking. (Strings are accepted too, as long as they give the path to an existing node.) This function is used for /chosen and /aliases. - A new 'type: phandle' type can now be given in bindings, for properties that are assigned like 'foo = < &node >;'. - Property.__str__() now displays phandles and path references as they were written (e.g. '< &foo >' instead of '< 0x1 >', if the allocated phandle happened to be 1). - Property.to_num() and Property.to_nums() no longer take a 'length' parameter, because it makes no sense with the type checking. - The global dtlib.to_string() and dtlib.to_strings() functions were removed, because they're not that useful. - More tests were added, along with misc. minor cleanup in various places. - Probably other stuff I forgot. The more strict type checking in dtlib indirectly makes some parts of edtlib more strict as well (wherever Property.to_*() is used). Fixes: #18131 Signed-off-by: Ulf Magnusson <Ulf.Magnusson@nordicsemi.no>
2019-08-09 20:38:17 +02:00
existent-boolean;
dts: Add new DTS/binding parser Add a new DTS/binding parser to scripts/dts/ for generating generated_dts_board.conf and generated_dts_board_unfixed.h. The old code is kept to generate some deprecated defines, using the --deprecated-only flag. It will be removed later. The new parser is implemented in three files in scripts/dts/: dtlib.py: A low-level .dts parsing library. This is similar to devicetree.py in the old code, but is a general robust DTS parser that doesn't rely on preprocessing. edtlib.py (e for extended): A library built on top of dtlib.py that brings together data from DTS files and bindings and creates Device instances with all the data for a device. gen_defines.py: A script that uses edtlib.py to generate generated_dts_board.conf and generated_dts_board_unfixed.h. Corresponds to extract_dts_includes.py and the files in extract/ in the old code. testdtlib.py: Test suite for dtlib.py. Can be run directly as a script. testedtlib.py (uses test.dts and test-bindings/): Test suite for edtlib.py. Can be run directly as a script. The test suites will be run automatically in CI. The new code turns some things that were warnings (or not checked) in the old code into errors, like missing properties that are specified with 'category: required' in the binding for the node. The code includes lots of documentation and tries to give helpful error messages instead of Python errors. Co-authored-by: Kumar Gala <kumar.gala@linaro.org> Signed-off-by: Ulf Magnusson <Ulf.Magnusson@nordicsemi.no>
2018-12-17 20:09:47 +01:00
int = <1>;
array = <1 2 3>;
uint8-array = [ 12 34 ];
string = "foo";
string-array = "foo", "bar", "baz";
phandle-ref = < &{/ctrl-1} >;
phandle-refs = < &{/ctrl-1} &{/ctrl-2} >;
phandle-array-foos = < &{/ctrl-1} 1 &{/ctrl-2} 2 3 >;
foo-gpios = < &{/ctrl-1} 1 >;
path = &{/ctrl-1};
};
dts: dtlib/edtlib: Add a syntax-based type-checking system Property type-checking has been pretty rudimentary until now, only checking things like the length being divisible by 4 for 'type: array', and strings being null-terminated. In particular, no checking was done for 'type: uint8-array', letting jedec-id = < 0xc8 0x28 0x17 >; slip through when jedec-id = [ 0xc8 0x28 0x17 ]; was intended. Fix it by adding a syntax-based type checker: 1. Add Property.type, which gives a high-level type for the property, derived from the markers added in the previous commit. This includes types like TYPE_EMPTY ('foo;'), TYPE_NUM ('foo = < 3 >;'), TYPE_BYTES ('foo = [ 01 02 ];'), TYPE_STRINGS ('foo = "bar", "baz"'), TYPE_PHANDLE ('foo = < &bar >;'), and TYPE_COMPOUND (everything not recognized). See the Property.type docstring in dtlib for more info. 2. Use the high-level type in Property.to_num()/to_string()/to_node()/etc. to verify that the property was assigned in an expected way for the type. If the assignment looks bad, give a helpful error: expected property 'nums' on /foo/bar in some.dts to be assigned with 'nums = < (number) (number) ... >', not 'nums = "oops";' Some other related changes are included as well: - There's a new Property.to_bytes() function that works like accessing Property.bytes, except with an added check for the value being assigned like 'foo = [ ... ]'. This function solves problems like the jedec-id one. - There's a new Property.to_path() function for fetching the referenced node for assignments like 'foo = &node;', with type checking. (Strings are accepted too, as long as they give the path to an existing node.) This function is used for /chosen and /aliases. - A new 'type: phandle' type can now be given in bindings, for properties that are assigned like 'foo = < &node >;'. - Property.__str__() now displays phandles and path references as they were written (e.g. '< &foo >' instead of '< 0x1 >', if the allocated phandle happened to be 1). - Property.to_num() and Property.to_nums() no longer take a 'length' parameter, because it makes no sense with the type checking. - The global dtlib.to_string() and dtlib.to_strings() functions were removed, because they're not that useful. - More tests were added, along with misc. minor cleanup in various places. - Probably other stuff I forgot. The more strict type checking in dtlib indirectly makes some parts of edtlib more strict as well (wherever Property.to_*() is used). Fixes: #18131 Signed-off-by: Ulf Magnusson <Ulf.Magnusson@nordicsemi.no>
2019-08-09 20:38:17 +02:00
ctrl-1 {
compatible = "phandle-array-controller-1";
#phandle-array-foo-cells = <1>;
#gpio-cells = <1>;
};
ctrl-2 {
compatible = "phandle-array-controller-2";
#phandle-array-foo-cells = <2>;
scripts: dts: Generalize handling of phandle-array types Generating generic information for 'type: phandle-array' properties in edtlib was difficult due to defining phandle-array as just a list of phandles and numbers. To make sense of a phandle-array property like 'pwms', you have to know that #pwm-cells is expected to appear on each referenced controller, and that the binding for the controller has a #cells. Because of this, handling of various 'type: phandle-array' properties was previously hardcoded in edtlib and exposed through properties like Node.pwms, instead of through the generic Node.props (though with a lot of shared code). In practice, it turns out that all 'type: phandle-array' properties in Zephyr work exactly the same way: They all have names that end in -s, the 's' is removed to derive the name of related properties, and they all look up #cells in the binding for the controller, which gives names to the data values. Strengthen the definition of 'type: phandle-array' to mean a property that works exactly like the existing phandle-array properties (which also means requiring that the name ends in -s). This removes a ton of hardcoding from edtlib and allows new 'type: phandle-array' properties to be added without making any code changes. If we ever need a property type that's a list of phandles and numbers but that doesn't follow this scheme, then we could add a separate type for it. We should check if the standard scheme is fine first though. The only property type for which no information is generated is now 'compound'. There's some inconsistency in how we generate identifiers for clocks compared to other 'type: phandle-array' properties, so keep special-casing them for now in gen_defines.py (see the comment in write_clocks()). This change also enabled a bunch of other simplifications, like reusing the ControllerAndData class for interrupts. Piggyback generalization of *-map properties so that they work for any phandle-array properties. It's now possible to have things like 'io-channel-map', if you need to. Signed-off-by: Ulf Magnusson <Ulf.Magnusson@nordicsemi.no>
2019-09-23 09:10:22 +02:00
};
props-2 {
compatible = "props";
phandle-array-foos = < &{/ctrl-0-1} 0 &{/ctrl-0-2} >;
phandle-array-foo-names = "a", "missing", "b";
};
ctrl-0-1 {
compatible = "phandle-array-controller-0";
#phandle-array-foo-cells = <0>;
};
ctrl-0-2 {
compatible = "phandle-array-controller-0";
#phandle-array-foo-cells = <0>;
};
scripts: dts: Generalize handling of phandle-array types Generating generic information for 'type: phandle-array' properties in edtlib was difficult due to defining phandle-array as just a list of phandles and numbers. To make sense of a phandle-array property like 'pwms', you have to know that #pwm-cells is expected to appear on each referenced controller, and that the binding for the controller has a #cells. Because of this, handling of various 'type: phandle-array' properties was previously hardcoded in edtlib and exposed through properties like Node.pwms, instead of through the generic Node.props (though with a lot of shared code). In practice, it turns out that all 'type: phandle-array' properties in Zephyr work exactly the same way: They all have names that end in -s, the 's' is removed to derive the name of related properties, and they all look up #cells in the binding for the controller, which gives names to the data values. Strengthen the definition of 'type: phandle-array' to mean a property that works exactly like the existing phandle-array properties (which also means requiring that the name ends in -s). This removes a ton of hardcoding from edtlib and allows new 'type: phandle-array' properties to be added without making any code changes. If we ever need a property type that's a list of phandles and numbers but that doesn't follow this scheme, then we could add a separate type for it. We should check if the standard scheme is fine first though. The only property type for which no information is generated is now 'compound'. There's some inconsistency in how we generate identifiers for clocks compared to other 'type: phandle-array' properties, so keep special-casing them for now in gen_defines.py (see the comment in write_clocks()). This change also enabled a bunch of other simplifications, like reusing the ControllerAndData class for interrupts. Piggyback generalization of *-map properties so that they work for any phandle-array properties. It's now possible to have things like 'io-channel-map', if you need to. Signed-off-by: Ulf Magnusson <Ulf.Magnusson@nordicsemi.no>
2019-09-23 09:10:22 +02:00
//
// Test <prefix>-map, via gpio-map
//
gpio-map {
source {
compatible = "gpio-src";
foo-gpios = <&{/gpio-map/connector} 3 4
&{/gpio-map/connector} 1 2>;
};
connector {
#gpio-cells = <2>;
// Use different data lengths for source and
// destination to make it a bit trickier
gpio-map = <1 2 &{/gpio-map/destination} 5
3 4 &{/gpio-map/destination} 6>;
};
destination {
compatible = "gpio-dst";
gpio-controller;
#gpio-cells = <1>;
};
dts: Add new DTS/binding parser Add a new DTS/binding parser to scripts/dts/ for generating generated_dts_board.conf and generated_dts_board_unfixed.h. The old code is kept to generate some deprecated defines, using the --deprecated-only flag. It will be removed later. The new parser is implemented in three files in scripts/dts/: dtlib.py: A low-level .dts parsing library. This is similar to devicetree.py in the old code, but is a general robust DTS parser that doesn't rely on preprocessing. edtlib.py (e for extended): A library built on top of dtlib.py that brings together data from DTS files and bindings and creates Device instances with all the data for a device. gen_defines.py: A script that uses edtlib.py to generate generated_dts_board.conf and generated_dts_board_unfixed.h. Corresponds to extract_dts_includes.py and the files in extract/ in the old code. testdtlib.py: Test suite for dtlib.py. Can be run directly as a script. testedtlib.py (uses test.dts and test-bindings/): Test suite for edtlib.py. Can be run directly as a script. The test suites will be run automatically in CI. The new code turns some things that were warnings (or not checked) in the old code into errors, like missing properties that are specified with 'category: required' in the binding for the node. The code includes lots of documentation and tries to give helpful error messages instead of Python errors. Co-authored-by: Kumar Gala <kumar.gala@linaro.org> Signed-off-by: Ulf Magnusson <Ulf.Magnusson@nordicsemi.no>
2018-12-17 20:09:47 +01:00
};
//
scripts: dts: Generalize handling of phandle-array types Generating generic information for 'type: phandle-array' properties in edtlib was difficult due to defining phandle-array as just a list of phandles and numbers. To make sense of a phandle-array property like 'pwms', you have to know that #pwm-cells is expected to appear on each referenced controller, and that the binding for the controller has a #cells. Because of this, handling of various 'type: phandle-array' properties was previously hardcoded in edtlib and exposed through properties like Node.pwms, instead of through the generic Node.props (though with a lot of shared code). In practice, it turns out that all 'type: phandle-array' properties in Zephyr work exactly the same way: They all have names that end in -s, the 's' is removed to derive the name of related properties, and they all look up #cells in the binding for the controller, which gives names to the data values. Strengthen the definition of 'type: phandle-array' to mean a property that works exactly like the existing phandle-array properties (which also means requiring that the name ends in -s). This removes a ton of hardcoding from edtlib and allows new 'type: phandle-array' properties to be added without making any code changes. If we ever need a property type that's a list of phandles and numbers but that doesn't follow this scheme, then we could add a separate type for it. We should check if the standard scheme is fine first though. The only property type for which no information is generated is now 'compound'. There's some inconsistency in how we generate identifiers for clocks compared to other 'type: phandle-array' properties, so keep special-casing them for now in gen_defines.py (see the comment in write_clocks()). This change also enabled a bunch of other simplifications, like reusing the ControllerAndData class for interrupts. Piggyback generalization of *-map properties so that they work for any phandle-array properties. It's now possible to have things like 'io-channel-map', if you need to. Signed-off-by: Ulf Magnusson <Ulf.Magnusson@nordicsemi.no>
2019-09-23 09:10:22 +02:00
// For testing Node.props with 'default:' values in binding
//
defaults {
compatible = "defaults";
// Should override the 'default:' in the binding
default-not-used = <234>;
};
//
// For testing 'enum:'
//
enums {
compatible = "enums";
int-enum = <1>;
string-enum = "foo_bar";
tokenizable-enum = "123 is ok";
tokenizable-lower-enum = "bar";
no-enum = "baz";
};
//
// For testing 'bus:' and 'on-bus:'
//
buses {
// The 'node' nodes below will map to different bindings since
// they appear on different buses
foo-bus {
compatible = "foo-bus";
edtlib: Match any parent bus when binding lacks an explicit on-bus There are some drivers in the tree that support devices on multiple different buses, although so far this has not been represented in device tree using the bus concept. In order to convert these drivers & bindings to refer to a formal bus in device tree we need to be able to match bindings which lack an explicit "on-bus: ..." value against any parent bus. This will also be needed for any external bindings, since those would not be aware of on-bus (as it's a Zephyhr-specific extension). The two drivers I'm particularly targeting is the ns16550 UART driver (drivers/serial/uart_ns16550.c) and the DW I2C driver (drivers/i2c/i2c_dw.c). They both support devices with a fixed MMIO address as well as devices connected and discovered over PCIe. The only issue is that instead of encoding the bus information the proper DT way these bindings use a special "pcie" property in the DT node entries to indicate whether the node is on the PCIe bus or not. Being able to convert the above two drivers to use the DT bus concept allow the removal of "hacks" like this: if DT_INST_PROP(0, pcie) || \ DT_INST_PROP(1, pcie) || \ DT_INST_PROP(2, pcie) || \ DT_INST_PROP(3, pcie) to the more intuitive: if DT_ANY_INST_ON_BUS_STATUS_OKAY(pcie) This also has the benefit that the driver doesn't need to make any arbitrary assumptions of how many matching devices there may be but works for any number of matches. This is already a problem now since e.g. the ns16550 driver assumes a maximum of 4 nodes, whereas dts/x86/elkhart_lake.dtsi defines up to 9 different ns16550 nodes. Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
2020-12-21 12:52:32 +02:00
node1 {
compatible = "on-bus", "on-any-bus";
nested {
compatible = "on-bus";
};
};
edtlib: Match any parent bus when binding lacks an explicit on-bus There are some drivers in the tree that support devices on multiple different buses, although so far this has not been represented in device tree using the bus concept. In order to convert these drivers & bindings to refer to a formal bus in device tree we need to be able to match bindings which lack an explicit "on-bus: ..." value against any parent bus. This will also be needed for any external bindings, since those would not be aware of on-bus (as it's a Zephyhr-specific extension). The two drivers I'm particularly targeting is the ns16550 UART driver (drivers/serial/uart_ns16550.c) and the DW I2C driver (drivers/i2c/i2c_dw.c). They both support devices with a fixed MMIO address as well as devices connected and discovered over PCIe. The only issue is that instead of encoding the bus information the proper DT way these bindings use a special "pcie" property in the DT node entries to indicate whether the node is on the PCIe bus or not. Being able to convert the above two drivers to use the DT bus concept allow the removal of "hacks" like this: if DT_INST_PROP(0, pcie) || \ DT_INST_PROP(1, pcie) || \ DT_INST_PROP(2, pcie) || \ DT_INST_PROP(3, pcie) to the more intuitive: if DT_ANY_INST_ON_BUS_STATUS_OKAY(pcie) This also has the benefit that the driver doesn't need to make any arbitrary assumptions of how many matching devices there may be but works for any number of matches. This is already a problem now since e.g. the ns16550 driver assumes a maximum of 4 nodes, whereas dts/x86/elkhart_lake.dtsi defines up to 9 different ns16550 nodes. Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
2020-12-21 12:52:32 +02:00
node2 {
compatible = "on-any-bus", "on-bus";
};
};
bar-bus {
compatible = "bar-bus";
node {
compatible = "on-bus";
};
};
edtlib: Match any parent bus when binding lacks an explicit on-bus There are some drivers in the tree that support devices on multiple different buses, although so far this has not been represented in device tree using the bus concept. In order to convert these drivers & bindings to refer to a formal bus in device tree we need to be able to match bindings which lack an explicit "on-bus: ..." value against any parent bus. This will also be needed for any external bindings, since those would not be aware of on-bus (as it's a Zephyhr-specific extension). The two drivers I'm particularly targeting is the ns16550 UART driver (drivers/serial/uart_ns16550.c) and the DW I2C driver (drivers/i2c/i2c_dw.c). They both support devices with a fixed MMIO address as well as devices connected and discovered over PCIe. The only issue is that instead of encoding the bus information the proper DT way these bindings use a special "pcie" property in the DT node entries to indicate whether the node is on the PCIe bus or not. Being able to convert the above two drivers to use the DT bus concept allow the removal of "hacks" like this: if DT_INST_PROP(0, pcie) || \ DT_INST_PROP(1, pcie) || \ DT_INST_PROP(2, pcie) || \ DT_INST_PROP(3, pcie) to the more intuitive: if DT_ANY_INST_ON_BUS_STATUS_OKAY(pcie) This also has the benefit that the driver doesn't need to make any arbitrary assumptions of how many matching devices there may be but works for any number of matches. This is already a problem now since e.g. the ns16550 driver assumes a maximum of 4 nodes, whereas dts/x86/elkhart_lake.dtsi defines up to 9 different ns16550 nodes. Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
2020-12-21 12:52:32 +02:00
no-bus-node {
compatible = "on-any-bus";
};
};
dts: Add new DTS/binding parser Add a new DTS/binding parser to scripts/dts/ for generating generated_dts_board.conf and generated_dts_board_unfixed.h. The old code is kept to generate some deprecated defines, using the --deprecated-only flag. It will be removed later. The new parser is implemented in three files in scripts/dts/: dtlib.py: A low-level .dts parsing library. This is similar to devicetree.py in the old code, but is a general robust DTS parser that doesn't rely on preprocessing. edtlib.py (e for extended): A library built on top of dtlib.py that brings together data from DTS files and bindings and creates Device instances with all the data for a device. gen_defines.py: A script that uses edtlib.py to generate generated_dts_board.conf and generated_dts_board_unfixed.h. Corresponds to extract_dts_includes.py and the files in extract/ in the old code. testdtlib.py: Test suite for dtlib.py. Can be run directly as a script. testedtlib.py (uses test.dts and test-bindings/): Test suite for edtlib.py. Can be run directly as a script. The test suites will be run automatically in CI. The new code turns some things that were warnings (or not checked) in the old code into errors, like missing properties that are specified with 'category: required' in the binding for the node. The code includes lots of documentation and tries to give helpful error messages instead of Python errors. Co-authored-by: Kumar Gala <kumar.gala@linaro.org> Signed-off-by: Ulf Magnusson <Ulf.Magnusson@nordicsemi.no>
2018-12-17 20:09:47 +01:00
//
// Node with 'child-binding:' in binding (along with a recursive
// 'child-binding:')
dts: Add new DTS/binding parser Add a new DTS/binding parser to scripts/dts/ for generating generated_dts_board.conf and generated_dts_board_unfixed.h. The old code is kept to generate some deprecated defines, using the --deprecated-only flag. It will be removed later. The new parser is implemented in three files in scripts/dts/: dtlib.py: A low-level .dts parsing library. This is similar to devicetree.py in the old code, but is a general robust DTS parser that doesn't rely on preprocessing. edtlib.py (e for extended): A library built on top of dtlib.py that brings together data from DTS files and bindings and creates Device instances with all the data for a device. gen_defines.py: A script that uses edtlib.py to generate generated_dts_board.conf and generated_dts_board_unfixed.h. Corresponds to extract_dts_includes.py and the files in extract/ in the old code. testdtlib.py: Test suite for dtlib.py. Can be run directly as a script. testedtlib.py (uses test.dts and test-bindings/): Test suite for edtlib.py. Can be run directly as a script. The test suites will be run automatically in CI. The new code turns some things that were warnings (or not checked) in the old code into errors, like missing properties that are specified with 'category: required' in the binding for the node. The code includes lots of documentation and tries to give helpful error messages instead of Python errors. Co-authored-by: Kumar Gala <kumar.gala@linaro.org> Signed-off-by: Ulf Magnusson <Ulf.Magnusson@nordicsemi.no>
2018-12-17 20:09:47 +01:00
//
child-binding {
compatible = "top-binding";
child-1 {
child-prop = <1>;
grandchild {
grandchild-prop = <2>;
};
};
child-2 {
child-prop = <3>;
dts: Add new DTS/binding parser Add a new DTS/binding parser to scripts/dts/ for generating generated_dts_board.conf and generated_dts_board_unfixed.h. The old code is kept to generate some deprecated defines, using the --deprecated-only flag. It will be removed later. The new parser is implemented in three files in scripts/dts/: dtlib.py: A low-level .dts parsing library. This is similar to devicetree.py in the old code, but is a general robust DTS parser that doesn't rely on preprocessing. edtlib.py (e for extended): A library built on top of dtlib.py that brings together data from DTS files and bindings and creates Device instances with all the data for a device. gen_defines.py: A script that uses edtlib.py to generate generated_dts_board.conf and generated_dts_board_unfixed.h. Corresponds to extract_dts_includes.py and the files in extract/ in the old code. testdtlib.py: Test suite for dtlib.py. Can be run directly as a script. testedtlib.py (uses test.dts and test-bindings/): Test suite for edtlib.py. Can be run directly as a script. The test suites will be run automatically in CI. The new code turns some things that were warnings (or not checked) in the old code into errors, like missing properties that are specified with 'category: required' in the binding for the node. The code includes lots of documentation and tries to give helpful error messages instead of Python errors. Co-authored-by: Kumar Gala <kumar.gala@linaro.org> Signed-off-by: Ulf Magnusson <Ulf.Magnusson@nordicsemi.no>
2018-12-17 20:09:47 +01:00
};
};
//
// zephyr,user binding inference
//
zephyr,user {
boolean;
bytes = [81 82 83];
number = <23>;
numbers = <1>, <2>, <3>;
string = "text";
strings = "a", "b", "c";
handle = <&{/ctrl-1}>;
phandles = <&{/ctrl-1}>, <&{/ctrl-2}>;
phandle-array-foos = <&{/ctrl-2} 1 2>;
};
//
// For testing that neither 'include: [foo.yaml, bar.yaml]' nor
// 'include: [bar.yaml, foo.yaml]' causes errors when one of the files
// has 'required: true' and the other 'required: false'
//
include-order {
node-1 {
compatible = "order-1";
foo = <1>;
};
node-2 {
compatible = "order-2";
foo = <2>;
};
};
//
// For testing deprecated property
//
test-deprecated {
compatible = "test-deprecated";
oldprop = <4>; /* deprecated property */
curprop = <5>;
};
//
// For testing deprecated features
//
deprecated {
compatible = "deprecated";
required = <1>;
required-2 = <2>;
#foo-cells = <2>;
sub-node {
foos = <&{/deprecated} 1 2>;
};
};
dts: Add new DTS/binding parser Add a new DTS/binding parser to scripts/dts/ for generating generated_dts_board.conf and generated_dts_board_unfixed.h. The old code is kept to generate some deprecated defines, using the --deprecated-only flag. It will be removed later. The new parser is implemented in three files in scripts/dts/: dtlib.py: A low-level .dts parsing library. This is similar to devicetree.py in the old code, but is a general robust DTS parser that doesn't rely on preprocessing. edtlib.py (e for extended): A library built on top of dtlib.py that brings together data from DTS files and bindings and creates Device instances with all the data for a device. gen_defines.py: A script that uses edtlib.py to generate generated_dts_board.conf and generated_dts_board_unfixed.h. Corresponds to extract_dts_includes.py and the files in extract/ in the old code. testdtlib.py: Test suite for dtlib.py. Can be run directly as a script. testedtlib.py (uses test.dts and test-bindings/): Test suite for edtlib.py. Can be run directly as a script. The test suites will be run automatically in CI. The new code turns some things that were warnings (or not checked) in the old code into errors, like missing properties that are specified with 'category: required' in the binding for the node. The code includes lots of documentation and tries to give helpful error messages instead of Python errors. Co-authored-by: Kumar Gala <kumar.gala@linaro.org> Signed-off-by: Ulf Magnusson <Ulf.Magnusson@nordicsemi.no>
2018-12-17 20:09:47 +01:00
};