Make it possible to do device tree validation on
dts/dtsi during development and preparation for
upstream.

Signed-off-by: Bruno Thomsen <[email protected]>
---
v1 -> v2 changed:
- Move complexity from kernel.make to ptxd_make_world_dtb
- KERNEL_DTB_CHECK_OPT conditional on KERNEL_DTB_CHECK
- Move KERNEL_DTB_CHECK inside 'if KERNEL_DTB'
- Clarify in help that schema problems are warnings
---
 platforms/kernel.in                 | 25 ++++++++++++++++++++++
 rules/kernel.make                   |  7 +++++++
 rules/post/ptxd_make_world_dtb.make |  1 +
 scripts/lib/ptxd_make_world_dtb.sh  | 32 +++++++++++++++++++++++++++++
 4 files changed, 65 insertions(+)

diff --git a/platforms/kernel.in b/platforms/kernel.in
index 2c6d906e8..36a4f3cf0 100644
--- a/platforms/kernel.in
+++ b/platforms/kernel.in
@@ -11,6 +11,8 @@ menuconfig KERNEL
        select HOST_LZ4                 if KERNEL_LZ4
        select HOST_LIBKMOD             if KERNEL_MODULES
        select HOST_SYSTEM_BC
+       select HOST_SYSTEM_PYTHON3      if KERNEL_DTB_CHECK
+       select HOST_SYSTEM_PYTHON3_DTSCHEMA     if KERNEL_DTB_CHECK
        select HOST_OPENSSL             if KERNEL_OPENSSL
        select HOST_LIBELF              if KERNEL_LIBELF
        select HOST_BINDGEN_CLI         if KERNEL_RUST
@@ -200,6 +202,29 @@ config KERNEL_DTS
          is used as a search path for the device tree files specified
          here. Multiple dts files can be specified, separated by spaces.
 
+config KERNEL_DTB_CHECK
+       bool
+       prompt "validate device trees against the DT schema"
+       help
+         Additionally build the device trees with the kernel build system
+         ('make CHECK_DTBS=y <board>.dtb') to validate them against the
+         device tree bindings in Documentation/devicetree/bindings.
+         Schema problems are reported as warnings, so they do not break
+         the build.
+
+         This requires the 'dtschema' python package on the build host and
+         it noticeably increases the build time of the kernel, because the
+         schema of all bindings must be processed first.
+
+         Only device trees that are part of the kernel tree can be checked,
+         because the make targets are relative to arch/<arch>/boot/dts.
+         Each file in KERNEL_DTS is looked up in KERNEL_DTS_PATH and the
+         first match inside the kernel tree is validated. Device trees
+         without such a match are skipped with a warning. So for device
+         trees in a vendor directory, that directory must be part of
+         KERNEL_DTS_PATH, e.g.
+         "${KERNEL_DIR}/arch/${GENERIC_KERNEL_ARCH}/boot/dts/ti/omap".
+
 config KERNEL_DTS_SUPPORT_OVERLAYS
        bool
 
diff --git a/rules/kernel.make b/rules/kernel.make
index af0dd3913..d32a0443c 100644
--- a/rules/kernel.make
+++ b/rules/kernel.make
@@ -282,6 +282,13 @@ KERNEL_INSTALL_OPT = \
        $(KERNEL_BASE_OPT) \
        modules_install
 
+ifdef PTXCONF_KERNEL_DTB_CHECK
+# validate the device trees while building them in world/dtb
+KERNEL_DTB_CHECK_OPT   = \
+       $(KERNEL_SHARED_OPT) \
+       CHECK_DTBS=y
+endif
+
 $(STATEDIR)/kernel.install:
        @$(call targetinfo)
 ifdef PTXCONF_KERNEL_MODULES_INSTALL
diff --git a/rules/post/ptxd_make_world_dtb.make 
b/rules/post/ptxd_make_world_dtb.make
index 37468c0be..81b237a87 100644
--- a/rules/post/ptxd_make_world_dtb.make
+++ b/rules/post/ptxd_make_world_dtb.make
@@ -10,6 +10,7 @@ world/dtb/env = \
        $(call world/env, $(1)) \
        pkg_dts_path="$($(1)_DTS_PATH)" \
        pkg_dts="$($(1)_DTS)" \
+       pkg_dtb_check_opt="$(call ptx/escape,$($(1)_DTB_CHECK_OPT))" \
        pkg_arch="$(GENERIC_KERNEL_ARCH)"
 
 world/dtb = \
diff --git a/scripts/lib/ptxd_make_world_dtb.sh 
b/scripts/lib/ptxd_make_world_dtb.sh
index dea9268ff..22622b2ad 100644
--- a/scripts/lib/ptxd_make_world_dtb.sh
+++ b/scripts/lib/ptxd_make_world_dtb.sh
@@ -109,10 +109,13 @@ export -f ptxd_make_world_dtbo
 
 ptxd_make_world_dtb() {
     local dtb_deps_target dtb_source dtb_target
+    local dts_file dts_in_tree dtb_check_dtstree
+    local -a dtb_check_targets=()
 
     ptxd_make_world_init || return
 
     dtb_deps_target="${ptx_state_dir}/${pkg_stamp}"
+    dtb_check_dtstree="${pkg_kernel_dir:-${pkg_dir}}/arch/${pkg_arch}/boot/dts"
 
     echo -e "\nBuilding device trees..."
 
@@ -128,7 +131,36 @@ ptxd_make_world_dtb() {
        dtb_source="${ptxd_reply}"
        dtb_target="${pkg_pkg_dir}/boot/$(basename ${dts_dts/%.dts/.dtb})"
 
+       #
+       # The dtb targets of the kernel build system are relative to
+       # arch/<arch>/boot/dts, so only device trees from the kernel tree
+       # can be validated.
+       #
+       if [ -n "${pkg_dtb_check_opt}" ]; then
+           dts_file=""
+           for dts_in_tree in "${ptxd_reply[@]}"; do
+               if [ "${dts_in_tree}" != "${dts_in_tree#${dtb_check_dtstree}/}" 
]; then
+                   dts_file="${dts_in_tree#${dtb_check_dtstree}/}"
+                   break
+               fi
+           done
+           if [ -n "${dts_file}" ]; then
+               
dtb_check_targets[${#dtb_check_targets[@]}]="${dts_file/%.dts/.dtb}"
+           else
+               ptxd_warning "Device tree '${dts_dts}' is not part of the 
kernel tree. Skipping validation."
+           fi
+       fi
+
        ptxd_make_dtb || break
     done
+
+    if [ ${#dtb_check_targets[@]} -ne 0 ]; then
+       echo -e "\nValidating device trees..."
+       ptxd_eval \
+           "${MAKE}" \
+           "${pkg_dtb_check_opt}" \
+           "${dtb_check_targets[@]}" ||
+       ptxd_bailout "Unable to validate device trees."
+    fi
 }
 export -f ptxd_make_world_dtb
-- 
2.55.0


Reply via email to