[v4] kbuild: Add support for DT binding schema checks

Message ID 20181211202406.27721-1-robh@kernel.org
State Accepted
Commit 4f0e3a57d6eb727c54249542c509e0b7aa122465
Headers show
Series
  • [v4] kbuild: Add support for DT binding schema checks
Related show

Commit Message

Rob Herring Dec. 11, 2018, 8:24 p.m.
This adds the build infrastructure for checking DT binding schema
documents and validating dts files using the binding schema.

Check DT binding schema documents:
make dt_binding_check

Build dts files and check using DT binding schema:
make dtbs_check

Optionally, DT_SCHEMA_FILES can be passed in with a schema file(s) to
use for validation. This makes it easier to find and fix errors
generated by a specific schema.

Currently, the validation targets are separate from a normal build to
avoid a hard dependency on the external DT schema project and because
there are lots of warnings generated.

Cc: Jonathan Corbet <corbet@lwn.net>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Masahiro Yamada <yamada.masahiro@socionext.com>
Cc: Michal Marek <michal.lkml@markovi.net>
Cc: linux-doc@vger.kernel.org
Cc: devicetree@vger.kernel.org
Cc: linux-kbuild@vger.kernel.org
Signed-off-by: Rob Herring <robh@kernel.org>

---
v4:
- Rework libyaml check and error message with Masahiro's version
- Simplify build rules and dependencies


 .gitignore                                   |  1 +
 Documentation/Makefile                       |  2 +-
 Documentation/devicetree/bindings/.gitignore |  2 ++
 Documentation/devicetree/bindings/Makefile   | 27 ++++++++++++++++++++
 Makefile                                     | 13 +++++++---
 scripts/Makefile.lib                         | 24 +++++++++++++++--
 scripts/dtc/Makefile                         |  4 +++
 7 files changed, 67 insertions(+), 6 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/.gitignore
 create mode 100644 Documentation/devicetree/bindings/Makefile

-- 
2.19.1

Comments

Rob Herring Jan. 27, 2019, 3 a.m. | #1
On Wed, Jan 23, 2019 at 9:33 AM Geert Uytterhoeven <geert@linux-m68k.org> wrote:
>

> Hi Rob,

>

> On Tue, Dec 11, 2018 at 9:24 PM Rob Herring <robh@kernel.org> wrote:

> > This adds the build infrastructure for checking DT binding schema

> > documents and validating dts files using the binding schema.

> >

> > Check DT binding schema documents:

> > make dt_binding_check

> >

> > Build dts files and check using DT binding schema:

> > make dtbs_check

> >

> > Optionally, DT_SCHEMA_FILES can be passed in with a schema file(s) to

> > use for validation. This makes it easier to find and fix errors

> > generated by a specific schema.

> >

> > Currently, the validation targets are separate from a normal build to

> > avoid a hard dependency on the external DT schema project and because

> > there are lots of warnings generated.

>

> Thanks, I'm giving this a try, and get errors like:

>

>       DTC     arch/arm/boot/dts/emev2-kzm9d.dt.yaml

>     FATAL ERROR: No markers present in property 'cpu0' value

>

> and

>

>       DTC     arch/arm64/boot/dts/renesas/r8a7795-salvator-x.dt.yaml

>     FATAL ERROR: No markers present in property 'audio_clk_a' value

>

> Do you have a clue?


That's really strange because those aren't even properties. Are other
dts files okay? This is the in tree dtc?

The only time you should be missing markers is if you did a dts -> dts
-> dt.yaml.

Rob
Geert Uytterhoeven Jan. 28, 2019, 9:43 a.m. | #2
Hi Rob,

On Tue, Dec 11, 2018 at 9:24 PM Rob Herring <robh@kernel.org> wrote:
> This adds the build infrastructure for checking DT binding schema

> documents and validating dts files using the binding schema.

>

> Check DT binding schema documents:

> make dt_binding_check

>

> Build dts files and check using DT binding schema:

> make dtbs_check

>

> Optionally, DT_SCHEMA_FILES can be passed in with a schema file(s) to

> use for validation. This makes it easier to find and fix errors

> generated by a specific schema.

>

> Currently, the validation targets are separate from a normal build to

> avoid a hard dependency on the external DT schema project and because

> there are lots of warnings generated.

>

> Cc: Jonathan Corbet <corbet@lwn.net>

> Cc: Mark Rutland <mark.rutland@arm.com>

> Cc: Masahiro Yamada <yamada.masahiro@socionext.com>

> Cc: Michal Marek <michal.lkml@markovi.net>

> Cc: linux-doc@vger.kernel.org

> Cc: devicetree@vger.kernel.org

> Cc: linux-kbuild@vger.kernel.org

> Signed-off-by: Rob Herring <robh@kernel.org>


BTW, what are the CONFIG dependencies for this to work?
E.g. defconfig on x86_64 fails, even after enabling CONFIG_OF:

$ make dt_binding_check
  SCHEMA  Documentation/devicetree/bindings/processed-schema.yaml
  CHKDT   Documentation/devicetree/bindings/arm/primecell.yaml
  ...
  CHKDT   Documentation/devicetree/bindings/trivial-devices.yaml
make[1]: *** No rule to make target
'Documentation/devicetree/bindings/arm/primecell.example.dtb', needed
by '__build'.  Stop.

Obviously it does work for arm/arm64.

Thanks!

Gr{oetje,eeting}s,

                        Geert

-- 
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds
Rob Herring Jan. 28, 2019, 3:34 p.m. | #3
On Mon, Jan 28, 2019 at 3:43 AM Geert Uytterhoeven <geert@linux-m68k.org> wrote:
>

> Hi Rob,

>

> On Tue, Dec 11, 2018 at 9:24 PM Rob Herring <robh@kernel.org> wrote:

> > This adds the build infrastructure for checking DT binding schema

> > documents and validating dts files using the binding schema.

> >

> > Check DT binding schema documents:

> > make dt_binding_check

> >

> > Build dts files and check using DT binding schema:

> > make dtbs_check

> >

> > Optionally, DT_SCHEMA_FILES can be passed in with a schema file(s) to

> > use for validation. This makes it easier to find and fix errors

> > generated by a specific schema.

> >

> > Currently, the validation targets are separate from a normal build to

> > avoid a hard dependency on the external DT schema project and because

> > there are lots of warnings generated.

> >

> > Cc: Jonathan Corbet <corbet@lwn.net>

> > Cc: Mark Rutland <mark.rutland@arm.com>

> > Cc: Masahiro Yamada <yamada.masahiro@socionext.com>

> > Cc: Michal Marek <michal.lkml@markovi.net>

> > Cc: linux-doc@vger.kernel.org

> > Cc: devicetree@vger.kernel.org

> > Cc: linux-kbuild@vger.kernel.org

> > Signed-off-by: Rob Herring <robh@kernel.org>

>

> BTW, what are the CONFIG dependencies for this to work?

> E.g. defconfig on x86_64 fails, even after enabling CONFIG_OF:


I generally use allmodconfig which enables building all DTs.

Yes, there's a dependency on CONFIG_DTC which isn't always enabled
with CONFIG_OF. Maybe it should be. The only other solutions I've
thought of are either always build dtc or make the targets conditional
on CONFIG_DTC. The latter would only change the error message.

Rob

Patch

diff --git a/.gitignore b/.gitignore
index 97ba6b79834c..a20ac26aa2f5 100644
--- a/.gitignore
+++ b/.gitignore
@@ -15,6 +15,7 @@ 
 *.bin
 *.bz2
 *.c.[012]*.*
+*.dt.yaml
 *.dtb
 *.dtb.S
 *.dwo
diff --git a/Documentation/Makefile b/Documentation/Makefile
index 2ca77ad0f238..9786957c6a35 100644
--- a/Documentation/Makefile
+++ b/Documentation/Makefile
@@ -2,7 +2,7 @@ 
 # Makefile for Sphinx documentation
 #
 
-subdir-y :=
+subdir-y := devicetree/bindings/
 
 # You can set these variables from the command line.
 SPHINXBUILD   = sphinx-build
diff --git a/Documentation/devicetree/bindings/.gitignore b/Documentation/devicetree/bindings/.gitignore
new file mode 100644
index 000000000000..ef82fcfcccab
--- /dev/null
+++ b/Documentation/devicetree/bindings/.gitignore
@@ -0,0 +1,2 @@ 
+*.example.dts
+processed-schema.yaml
diff --git a/Documentation/devicetree/bindings/Makefile b/Documentation/devicetree/bindings/Makefile
new file mode 100644
index 000000000000..6e5cef0ed6fb
--- /dev/null
+++ b/Documentation/devicetree/bindings/Makefile
@@ -0,0 +1,27 @@ 
+# SPDX-License-Identifier: GPL-2.0
+DT_DOC_CHECKER ?= dt-doc-validate
+DT_EXTRACT_EX ?= dt-extract-example
+DT_MK_SCHEMA ?= dt-mk-schema
+DT_MK_SCHEMA_FLAGS := $(if $(DT_SCHEMA_FILES), -u)
+
+quiet_cmd_chk_binding = CHKDT   $(patsubst $(srctree)/%,%,$<)
+      cmd_chk_binding = $(DT_DOC_CHECKER) $< ; \
+                        $(DT_EXTRACT_EX) $< > $@
+
+$(obj)/%.example.dts: $(src)/%.yaml FORCE
+	$(call if_changed,chk_binding)
+
+DT_TMP_SCHEMA := processed-schema.yaml
+extra-y += $(DT_TMP_SCHEMA)
+
+quiet_cmd_mk_schema = SCHEMA  $@
+      cmd_mk_schema = $(DT_MK_SCHEMA) $(DT_MK_SCHEMA_FLAGS) -o $@ $(filter-out FORCE, $^)
+
+DT_DOCS = $(shell cd $(srctree)/$(src) && find * -name '*.yaml')
+DT_SCHEMA_FILES ?= $(addprefix $(src)/,$(DT_DOCS))
+
+extra-y += $(patsubst $(src)/%.yaml,%.example.dts, $(DT_SCHEMA_FILES))
+extra-y += $(patsubst $(src)/%.yaml,%.example.dtb, $(DT_SCHEMA_FILES))
+
+$(obj)/$(DT_TMP_SCHEMA): $(DT_SCHEMA_FILES) FORCE
+	$(call if_changed,mk_schema)
diff --git a/Makefile b/Makefile
index 2f36db897895..a3e2db2a3119 100644
--- a/Makefile
+++ b/Makefile
@@ -1232,10 +1232,13 @@  ifneq ($(dtstree),)
 %.dtb: prepare3 scripts_dtc
 	$(Q)$(MAKE) $(build)=$(dtstree) $(dtstree)/$@
 
-PHONY += dtbs dtbs_install
-dtbs: prepare3 scripts_dtc
+PHONY += dtbs dtbs_install dt_binding_check
+dtbs dtbs_check: prepare3 scripts_dtc
 	$(Q)$(MAKE) $(build)=$(dtstree)
 
+dtbs_check: export CHECK_DTBS=1
+dtbs_check: dt_binding_check
+
 dtbs_install:
 	$(Q)$(MAKE) $(dtbinst)=$(dtstree)
 
@@ -1249,6 +1252,9 @@  PHONY += scripts_dtc
 scripts_dtc: scripts_basic
 	$(Q)$(MAKE) $(build)=scripts/dtc
 
+dt_binding_check: scripts_dtc
+	$(Q)$(MAKE) $(build)=Documentation/devicetree/bindings
+
 # ---------------------------------------------------------------------------
 # Modules
 
@@ -1611,7 +1617,8 @@  clean: $(clean-dirs)
 	$(call cmd,rmfiles)
 	@find $(if $(KBUILD_EXTMOD), $(KBUILD_EXTMOD), .) $(RCS_FIND_IGNORE) \
 		\( -name '*.[aios]' -o -name '*.ko' -o -name '.*.cmd' \
-		-o -name '*.ko.*' -o -name '*.dtb' -o -name '*.dtb.S' \
+		-o -name '*.ko.*' \
+		-o -name '*.dtb' -o -name '*.dtb.S' -o -name '*.dt.yaml' \
 		-o -name '*.dwo' -o -name '*.lst' \
 		-o -name '*.su'  \
 		-o -name '.*.d' -o -name '.*.tmp' -o -name '*.mod.c' \
diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib
index 8fe4468f9bda..723b33c942df 100644
--- a/scripts/Makefile.lib
+++ b/scripts/Makefile.lib
@@ -61,6 +61,11 @@  real-obj-m := $(foreach m, $(obj-m), $(if $(strip $($(m:.o=-objs)) $($(m:.o=-y))
 extra-y				+= $(dtb-y)
 extra-$(CONFIG_OF_ALL_DTBS)	+= $(dtb-)
 
+ifneq ($(CHECK_DTBS),)
+extra-y += $(patsubst %.dtb,%.dt.yaml, $(dtb-y))
+extra-$(CONFIG_OF_ALL_DTBS) += $(patsubst %.dtb,%.dt.yaml, $(dtb-))
+endif
+
 # Add subdir path
 
 extra-y		:= $(addprefix $(obj)/,$(extra-y))
@@ -284,13 +289,28 @@  $(obj)/%.dtb.S: $(obj)/%.dtb FORCE
 quiet_cmd_dtc = DTC     $@
 cmd_dtc = mkdir -p $(dir ${dtc-tmp}) ; \
 	$(HOSTCC) -E $(dtc_cpp_flags) -x assembler-with-cpp -o $(dtc-tmp) $< ; \
-	$(DTC) -O dtb -o $@ -b 0 \
+	$(DTC) -O $(2) -o $@ -b 0 \
 		$(addprefix -i,$(dir $<) $(DTC_INCLUDE)) $(DTC_FLAGS) \
 		-d $(depfile).dtc.tmp $(dtc-tmp) ; \
 	cat $(depfile).pre.tmp $(depfile).dtc.tmp > $(depfile)
 
 $(obj)/%.dtb: $(src)/%.dts $(DTC) FORCE
-	$(call if_changed_dep,dtc)
+	$(call if_changed_dep,dtc,dtb)
+
+DT_CHECKER ?= dt-validate
+DT_BINDING_DIR := Documentation/devicetree/bindings
+DT_TMP_SCHEMA := $(objtree)/$(DT_BINDING_DIR)/processed-schema.yaml
+
+quiet_cmd_dtb_check =	CHECK   $@
+      cmd_dtb_check =	$(DT_CHECKER) -p $(DT_TMP_SCHEMA) $@ ;
+
+define rule_dtc_dt_yaml
+	$(call cmd_and_fixdep,dtc,yaml)		\
+	$(call echo-cmd,dtb_check) $(cmd_dtb_check)
+endef
+
+$(obj)/%.dt.yaml: $(src)/%.dts $(DTC) $(DT_TMP_SCHEMA) FORCE
+	$(call if_changed_rule,dtc_dt_yaml)
 
 dtc-tmp = $(subst $(comma),_,$(dot-target).dts.tmp)
 
diff --git a/scripts/dtc/Makefile b/scripts/dtc/Makefile
index 056d5da6c477..5f227d8d39d8 100644
--- a/scripts/dtc/Makefile
+++ b/scripts/dtc/Makefile
@@ -12,6 +12,10 @@  dtc-objs	+= dtc-lexer.lex.o dtc-parser.tab.o
 HOST_EXTRACFLAGS := -I$(src)/libfdt
 
 ifeq ($(wildcard /usr/include/yaml.h),)
+ifneq ($(CHECK_DTBS),)
+$(error dtc needs libyaml for DT schema validation support. \
+	Install the necessary libyaml development package.)
+endif
 HOST_EXTRACFLAGS += -DNO_YAML
 else
 dtc-objs	+= yamltree.o