deviceTree: Allow applying dtoverlays for DT with no compatible string

In some cases vendor provided .dts's do not have a `compatible` string set
[example](https://github.com/raspberrypi/linux/blob/rpi-6.1.y/arch/arm/boot/dts/overlays/hat_map.dts).

Trying to patch them with `apply_overlays.py` results in an exception (and
therefore build error) even when the filter didn't match this .dtb.

These changes allow patching .dtbs with no `compatible` set, assuming they
are compatible with the overlay.

+13 -5
+13 -5
pkgs/os-specific/linux/device-tree/apply_overlays.py
··· 4 import json 5 from pathlib import Path 6 7 - from libfdt import Fdt, FdtException, FDT_ERR_NOSPACE, fdt_overlay_apply 8 9 10 @dataclass ··· 25 26 def get_compatible(fdt): 27 root_offset = fdt.path_offset("/") 28 - return set(fdt.getprop(root_offset, "compatible").as_stringlist()) 29 30 31 def apply_overlay(dt: Fdt, dto: Fdt) -> Fdt: ··· 77 with source_dt.open("rb") as fd: 78 dt = Fdt(fd.read()) 79 80 - dt_compatible = get_compatible(dt) 81 - 82 for overlay in overlays_data: 83 if overlay.filter and overlay.filter not in str(rel_path): 84 print(f" Skipping overlay {overlay.name}: filter does not match") 85 continue 86 87 - if not overlay.compatible.intersection(dt_compatible): 88 print(f" Skipping overlay {overlay.name}: {overlay.compatible} is incompatible with {dt_compatible}") 89 continue 90
··· 4 import json 5 from pathlib import Path 6 7 + from libfdt import Fdt, FdtException, FDT_ERR_NOSPACE, FDT_ERR_NOTFOUND, fdt_overlay_apply 8 9 10 @dataclass ··· 25 26 def get_compatible(fdt): 27 root_offset = fdt.path_offset("/") 28 + 29 + try: 30 + return set(fdt.getprop(root_offset, "compatible").as_stringlist()) 31 + except FdtException as e: 32 + if e.err == -FDT_ERR_NOTFOUND: 33 + return set() 34 + else: 35 + raise e 36 37 38 def apply_overlay(dt: Fdt, dto: Fdt) -> Fdt: ··· 84 with source_dt.open("rb") as fd: 85 dt = Fdt(fd.read()) 86 87 for overlay in overlays_data: 88 if overlay.filter and overlay.filter not in str(rel_path): 89 print(f" Skipping overlay {overlay.name}: filter does not match") 90 continue 91 92 + dt_compatible = get_compatible(dt) 93 + if len(dt_compatible) == 0: 94 + print(f" Device tree {rel_path} has no compatible string set. Assuming it's compatible with overlay") 95 + elif not overlay.compatible.intersection(dt_compatible): 96 print(f" Skipping overlay {overlay.name}: {overlay.compatible} is incompatible with {dt_compatible}") 97 continue 98