Bug 227974 - libfdt reverses order of child devices in overlays
Summary: libfdt reverses order of child devices in overlays
Status: Closed Not A Bug
Alias: None
Product: Base System
Classification: Unclassified
Component: arm (show other bugs)
Version: CURRENT
Hardware: Any Any
: --- Affects Many People
Assignee: freebsd-arm (Nobody)
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2018-05-04 17:50 UTC by Bob Frazier
Modified: 2019-06-05 15:49 UTC (History)
3 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Bob Frazier 2018-05-04 17:50:08 UTC
this probably affects more than just arm, but I have only observed it with arm.

When an overlay specifies more than one child device, such as in the example below:

&{/soc/spi@7e204000} {
        status = "okay";

        spigen0: spigen0 {
                compatible = "freebsd,spigen";
                reg = <0>;
                status = "okay";
        };
        spigen1: spigen1 {
                compatible = "freebsd,spigen";
                reg = <1>;
                status = "okay";
        };
};

"sysctl -b hw.fdt | dtc -I dtb -O dts" reports:

        spi@7e204000 {
                compatible = "brcm,bcm2835-spi";
                reg = <0x7e204000 0x1000>;
                interrupts = <0x2 0x16>;
                clocks = <0x4 0x14>;
                #address-cells = <0x1>;
                #size-cells = <0x0>;
                status = "okay";
                pinctrl-names = "default";
                pinctrl-0 = <0x36 0x37>;
                phandle = <0x3b>;
                spigen1 {
                        status = "okay";
                        reg = <0x1>;
                        compatible = "freebsd,spigen";
                };
                spigen0 {
                        status = "okay";
                        reg = <0x0>;
                        compatible = "freebsd,spigen";
                };
        };

In this case, it causes ofw_spibus_attach() in ofw_spibus.c to create the devices in the order specified in the FDT data, numbering them from 0 to 'n', even though the devices are specified as 'spigen1' and 'spigen0' in the FDT data, via the following function call:

    childdev = device_add_child(dev, NULL, -1);

this requires that the overlay child devices be specified in reverse order in order for them to appear with the specified device names 'spigen0' and 'spigen1'.

specifying spigen@0 and spigen@1 only causes the names to change (not the order reversal), and results in exactly the same problem.

It would seem that this problem would exist in the linux world as well, since everybody is using the same fdt library.  And changing the behavior of libfdt is probably a bad idea for this reason.


NOTE:  overlay is being loaded using 'fdt_overlays' in loader.conf


WORKAROUND:  specify child devices in the reverse order you want to create them in within the overlay.
Comment 1 Ian Lepore freebsd_committer freebsd_triage 2019-06-05 15:49:30 UTC
The names of FDT device nodes do not necessarily have any relationship to the names of devices instantiated by freebsd.  By FDT convention, a device node name is formed as devicetype@regaddr; it's just a coincidence in the case of spi that the register addresses are single-digit integers that seem to vaguely correspond with freebsd device names.  (And it should be noted that the names in the example shown do not follow the FDT rules and would generate a warning with the modern gnu dtc compiler because they should be spigen@0 not spigen0).

The root problem is that a user of spi devices needs some way to identify which /dev/spigenX device corresponds to which device described in the FDT data.  We ultimately solved that problem by naming spigen devices in devfs after their bus and chip select number, instead of just using sequential 0-n numbers.  So instead of spigen0 and spigen1, the example overlay would now create /dev/spigen0.0 and /dev/spigen0.1 (assume they were on spi bus zero), and since it's based on the chip select number it comes out the same name matter what order the nodes appear in.