Search code examples
linux-device-driverembedded-linuxdevice-tree

Linux Device Tree: Understanding how a reference to a deleted node works?


Context

I've taken a look at the device tree that is in use for a working i.MX6 based development board. I've noticed that in the case of the ethernet configuration, a confusing mix of directives are present. Namely:

  1. Node fec1 contains a directive to delete node mdio
  2. Node fec2 contains a reference to node ethphy1
  3. Node ethphy1 is within mdio, the deleted node.

Snippet

&fec1 {
        pinctrl-0 = <&pinctrl_enet1>, <&pinctrl_enet1_gpio>;
        /delete-node/ mdio;
};

&fec2 {
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_enet2>, <&pinctrl_enet2_gpio>, <&pinctrl_enet2_mdio>;
        phy-mode = "rmii";

        /* Reference */
        phy-handle = <&ethphy1>;
        phy-reset-gpios=<&gpio5 5 GPIO_ACTIVE_LOW>;
        phy-reset-duration=<100>;
        status = "okay";

        /* Deleted node */
        mdio {
                #address-cells = <1>;
                #size-cells = <0>;

                /* Referenced node */
                ethphy1: ethernet-phy@3 {
                        compatible = "ethernet-phy-ieee802.3-c22";
                        micrel,rmii-reference-clock-select-25-mhz;
                        micrel,led-mode = <0>;
                        clocks = <&rmii_ref_clk>;
                        clock-names = "rmii-ref";
                        reg = <3>;
                };
        };
};

Question

What is the final effect of deleting a node in which a child node is referenced? Is the reference broken. Is only the parent node deleted?


Solution

  • TL;DR version

    The /delete-node/ mdio; directive is deleting the mdio node that was added in imx6ul-imx6ull-var-som.dtsi or imx6ul-imx6ull-var-dart.dtsi.

    Full version

    OP pointed to imx6ul-imx6ull-var-som-concerto-board.dtsi as the source of the fragment. That is included by the following:

    One of those is included by at least the following, according to their imx6ul, imx6ull, or imx6ulz prefix:

    ims6ul:

    imx6ull:

    imx6ulz:

    Those all include one of the following, according to their imx6ul, imx6ull, or imx6ulz prefix:

    imx6ul:

    imx6ull:

    imx6ulz:

    imx6ul-imx6ull-var-som.dtsi and imx6ul-imx6ull-var-dart.dtsi both contain this section:

    &fec1 {
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_enet1>, <&pinctrl_enet1_gpio>, <&pinctrl_enet1_mdio>;
        phy-mode = "rmii";
        phy-reset-gpios=<&gpio5 0 GPIO_ACTIVE_LOW>;
        phy-reset-duration=<100>;
        phy-handle = <&ethphy0>;
        status = "okay";
    
        mdio {
            #address-cells = <1>;
            #size-cells = <0>;
    
            ethphy0: ethernet-phy@1 {
                compatible = "ethernet-phy-ieee802.3-c22";
                micrel,rmii-reference-clock-select-25-mhz;
                micrel,led-mode = <1>;
                clocks = <&rmii_ref_clk>;
                clock-names = "rmii-ref";
                reg = <1>;
            };
        };
    };
    

    That modifies the node referenced by &fec1 (which is defined in imx6ul.dtsi) and adds a sub-node called mdio. But the imx6ul-imx6ull-var-som-concerto-board.dtsi referred to by OP contains this section:

    &fec1 {
        pinctrl-0 = <&pinctrl_enet1>, <&pinctrl_enet1_gpio>;
        /delete-node/ mdio;
    };
    

    That also modifies the node referenced &fec1. The /delete-node/ mdio; directive removes the mdio sub-node added earlier.

    Effect of /delete-node/ in the device tree compiler

    Deleting a node with /delete-node/ removes the node, any label attached to the node, any properties contained in the node, and recursively, any nodes contained within the node. If the node being deleted by /delete-node/ does not exist, then the directive is silently ignored.

    If a node is deleted, any references to the node (or referenced to any label that was attached to the node) from elsewhere in the device tree source will no longer be valid, so the device tree compiler will produce an error "Reference to non-existent node or label" when compiling the source.

    Effect of /delete-node/ in device tree overlays

    The /delete-node/ directive only affects the source being compiled. If it is used in the source for a device tree overlay, the /delete-node/ directive will have no effect on the live device tree to which the overlay is applied. There is nothing in the compiled dtbo output to say that a node should be deleted from the live tree when the overlay is applied.

    What about /delete-property/?

    The /delete-property/ directive is similar to /delete-node/ except that it is for deleting a property and any label attached to the property.