mirror of
https://github.com/zephyrproject-rtos/zephyr
synced 2025-08-28 05:05:21 +00:00
API oversight. This was meant to be there all along together with Device.parent, for navigating the devicetree, but since a need for it never came up in gen_defines.py, it got overlooked. Devices are just devicetree nodes augmented with binding information and some interpretation of devicetree properties. I wonder if the name should be changed to something like edtlib.Node to make that clearer. Calling something like a flash partition a "device" is a bit weird, as Galak pointed out. I think I went with Device originally to avoid confusion with dtlib.Node, but since edtlib users don't directly interact with dtlib, it might not be that confusing in practice. Piggyback some documentation clarifications. Signed-off-by: Ulf Magnusson <Ulf.Magnusson@nordicsemi.no>
403 lines
7.6 KiB
Plaintext
403 lines
7.6 KiB
Plaintext
/*
|
|
* 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>;
|
|
};
|
|
};
|
|
|
|
//
|
|
// GPIOS
|
|
//
|
|
|
|
gpio-test {
|
|
controller-1 {
|
|
compatible = "gpio-two-cell";
|
|
#gpio-cells = <2>;
|
|
gpio-controller;
|
|
};
|
|
node {
|
|
gpios = <&{/gpio-test/controller-0} 1
|
|
&{/gpio-test/controller-1} 2 3>;
|
|
foo-gpios = <&{/gpio-test/controller-1} 4 5>;
|
|
bar-gpios = <&{/gpio-test/controller-1} 6 7>;
|
|
};
|
|
// Putting this controller last gives us some coverage for ordering
|
|
// issues during initialization
|
|
controller-0 {
|
|
compatible = "gpio-one-cell";
|
|
#gpio-cells = <1>;
|
|
gpio-controller;
|
|
};
|
|
};
|
|
|
|
//
|
|
// Clocks
|
|
//
|
|
|
|
clock-test {
|
|
fixed-clock {
|
|
// 'fixed-clock' is currently special-cased in the code
|
|
compatible = "fixed-clock";
|
|
#clock-cells = <0>;
|
|
clock-frequency = <123>;
|
|
};
|
|
clock-1 {
|
|
compatible = "clock-one-cell";
|
|
#clock-cells = <1>;
|
|
};
|
|
clock-2 {
|
|
compatible = "clock-two-cell";
|
|
#clock-cells = <2>;
|
|
};
|
|
node {
|
|
clocks = <&{/clock-test/fixed-clock}
|
|
&{/clock-test/clock-1} 1
|
|
&{/clock-test/clock-2} 1 2>;
|
|
clock-names = "fixed", "one-cell", "two-cell";
|
|
};
|
|
};
|
|
|
|
//
|
|
// PWMs
|
|
//
|
|
|
|
pwm-test {
|
|
pwm-0 {
|
|
compatible = "pwm-zero-cell";
|
|
#pwm-cells = <0>;
|
|
};
|
|
pwm-1 {
|
|
compatible = "pwm-one-cell";
|
|
#pwm-cells = <1>;
|
|
};
|
|
node {
|
|
pwms = <&{/pwm-test/pwm-0}
|
|
&{/pwm-test/pwm-1} 1>;
|
|
pwm-names = "zero-cell", "one-cell";
|
|
};
|
|
};
|
|
|
|
//
|
|
// IO channels
|
|
//
|
|
|
|
// Lots of common code with PWMs and clocks, so just test the basics
|
|
io-channel-test {
|
|
io-channel {
|
|
compatible = "io-channel";
|
|
#io-channel-cells = <1>;
|
|
};
|
|
node {
|
|
io-channels = <&{/io-channel-test/io-channel} 1>;
|
|
io-channel-names = "io-channel";
|
|
};
|
|
};
|
|
|
|
//
|
|
// '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>;
|
|
};
|
|
};
|
|
};
|
|
};
|
|
|
|
//
|
|
// For testing Device.parent and Device.children
|
|
//
|
|
|
|
parent {
|
|
child-1 {
|
|
};
|
|
child-2 {
|
|
grandchild {
|
|
};
|
|
};
|
|
};
|
|
|
|
//
|
|
// For testing 'include:'
|
|
//
|
|
|
|
binding-include {
|
|
compatible = "binding-include-test";
|
|
foo = <0>;
|
|
bar = <1>;
|
|
baz = <2>;
|
|
qaz = <3>;
|
|
};
|
|
|
|
//
|
|
// For testing Device.props (derived from 'properties:' in the binding)
|
|
//
|
|
|
|
props {
|
|
compatible = "props";
|
|
existent-boolean;
|
|
int = <1>;
|
|
array = <1 2 3>;
|
|
uint8-array = [ 12 34 ];
|
|
string = "foo";
|
|
string-array = "foo", "bar", "baz";
|
|
phandle-ref = < &{/props/node} >;
|
|
phandle-refs = < &{/props/node} &{/props/node2} >;
|
|
phandle-refs-and-vals = < &{/props/node} 1 &{/props/node2} 2 >;
|
|
|
|
node {
|
|
};
|
|
|
|
node2 {
|
|
};
|
|
};
|
|
|
|
//
|
|
// For testing Device.props with 'default:' values in binding
|
|
//
|
|
|
|
defaults {
|
|
compatible = "defaults";
|
|
// Should override the 'default:' in the binding
|
|
default-not-used = <234>;
|
|
};
|
|
|
|
//
|
|
// For testing 'child-bus:' and 'parent-bus:'
|
|
//
|
|
|
|
buses {
|
|
// The nodes below will map to different bindings since they
|
|
// appear on different buses
|
|
foo-bus {
|
|
compatible = "foo-bus";
|
|
node {
|
|
compatible = "on-bus";
|
|
};
|
|
};
|
|
bar-bus {
|
|
compatible = "bar-bus";
|
|
node {
|
|
compatible = "on-bus";
|
|
};
|
|
};
|
|
};
|
|
|
|
//
|
|
// Node with 'child-binding:' in binding (along with a recursive
|
|
// 'child-binding:')
|
|
//
|
|
|
|
child-binding {
|
|
compatible = "child-binding";
|
|
child-1 {
|
|
child-prop = <1>;
|
|
grandchild {
|
|
grandchild-prop = <2>;
|
|
};
|
|
};
|
|
child-2 {
|
|
child-prop = <3>;
|
|
};
|
|
};
|
|
|
|
//
|
|
// 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 features
|
|
//
|
|
|
|
deprecated {
|
|
compatible = "deprecated";
|
|
required = <1>;
|
|
required-2 = <2>;
|
|
sub-node {
|
|
child-prop = <3>;
|
|
};
|
|
};
|
|
};
|