Path references in overlays do not work, need hardcoded paths instead
There's a bunch of overlays (here and in bb.org-overlays) that create properties in /aliases
whose value is a node reference, e.g. BB-BBGG-WL1835-00A0.dts has:
aliases {
rtc0 = &extrtc;
rtc1 = "/ocp/rtc@44e3e000";
};
Node references (&extrtc
) are typically encountered inside an integer array (<...>
), which causes them to be replaced by the node's phandle. One outside an array, as is here the case, is replaced by the node's full path. This is basically a legacy thing used by some stuff inherited from Open Firmware, such as /aliases
and /chosen
.
These do not work in overlays and never have, since the overlay format only has support for fixing up phandles in properties, not paths. DTC of course doesn't warn about this but just sets the property to e.g. "/fragment@7/__overlay__/rtc@68";
or fails on an undefined reference if you're trying to reference a node that's not defined in the overlay.
The workaround is to use the what we see for rtc1: just convert the label to a path. Unfortunately however these paths will be kernel version dependent, and this particular path is wrong for the branch I found this in (v5.10.x-ti).
This managed to go unnoticed for a long time because as long as the AM335x RTC is reassigned to rtc1 (i.e. as long as the path is correct), the external rtc will end up getting assigned to rtc0 by the kernel even if it has no entry in /aliases
, since it's the first unused number. The fact that it works like that is kinda bad though, the kernel should have reserved "rtc0" in case the device it's assigned shows up, and the external rtc should therefore have become rtc2. Some other linux subsystems do actually get this right. (And if the kernel did that it wouldn't be necessary to manually move the built-in rtc to rtc1, the kernel would do that automatically if you assign some other device to be rtc0).