Description
Is your enhancement proposal related to a problem? Please describe.
Zephyr's current devicetree infrastructure does not support devicetree nodes having circular references. A few examples of this:
"Classic" circular reference
nodea: nodea {
status = "okay";
compatible = "vnd,deva";
dev-ref = <&nodeb>;
};
nodeb: nodeb {
status = "okay";
compatible = "vnd,devb";
dev-ref = <&nodea>;
};
Parent referencing child- this is also a circular reference
parent_node: parent {
status = "okay";
compatible = "vnd,dev-parent";
child-ref = <&child_node>;
child_node: child {
compatible = "vnd,dev-child";
status = "okay";
};
};
Any of these devicetrees will fail to compile, as the current devicetree scripting cannot create dependency ordinal numbers for all devicetree nodes when a circular reference exists. The key issue here is that we need to determine which of these nodes has a higher initialization priority, which is not clear from the circular reference.
Describe the solution you'd like
A method to support circular references in devicetree- One method that has been proposed by @mbolivar to handle this is treating circular references as a block of strongly connected components: https://en.wikipedia.org/wiki/Tarjan%27s_strongly_connected_components_algorithm.
Additional context
While this issue will affect any devicetree, the core driver behind the request is a way to support the sometimes complicate devicetree infrastructure needed to accurately describe display pipelines. One such example:
&mipi_dsi {
status = "okay";
ports {
#address-cells = <1>;
#size-cells = <0>;
port@0 {
reg = <0>;
dsi_in: endpoint {
remote-endpoint = <&dcnano_out>;
};
};
port@1 {
reg = <1>;
dsi_out: endpoint {
remote-endpoint = <&dsi_panel_in>;
};
};
};
rm68200@0 {
status = "okay";
compatible = "raydium,rm68200";
reg = <0x0>;
reset-gpios = <&gpio3 21 GPIO_ACTIVE_HIGH>;
data-lanes = <2>;
width = <720>;
height = <1280>;
pixel-clock = <6200000>;
pixel-format = <MIPI_DSI_PIXFMT_RGB565>;
width = <720>;
height = <1280>;
hsync = <8>;
hfp = <32>;
hbp = <32>;
vsync = <2>;
vfp = <16>;
vbp = <14>;
port {
dsi_panel_in: endpoint {
remote-endpoint = <&dsi_out>;
};
};
};
};
cc @gmarull