[v2,01/34] kbuild: Add support for DT binding schema checks

Message ID 20181203213223.16986-2-robh@kernel.org
State Superseded
Headers show
Series
  • [v2,01/34] kbuild: Add support for DT binding schema checks
Related show

Commit Message

Rob Herring Dec. 3, 2018, 9:31 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 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>

---
 .gitignore                                   |  1 +
 Documentation/Makefile                       |  2 +-
 Documentation/devicetree/bindings/.gitignore |  1 +
 Documentation/devicetree/bindings/Makefile   | 33 ++++++++++++++++++++
 Makefile                                     | 11 +++++--
 scripts/Makefile.lib                         | 24 ++++++++++++--
 6 files changed, 67 insertions(+), 5 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/.gitignore
 create mode 100644 Documentation/devicetree/bindings/Makefile

-- 
2.19.1

Comments

Masahiro Yamada Dec. 8, 2018, 4:47 a.m. | #1
Hi Rob,


On Tue, Dec 4, 2018 at 6:32 AM 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 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>

> ---

>  .gitignore                                   |  1 +

>  Documentation/Makefile                       |  2 +-

>  Documentation/devicetree/bindings/.gitignore |  1 +

>  Documentation/devicetree/bindings/Makefile   | 33 ++++++++++++++++++++

>  Makefile                                     | 11 +++++--

>  scripts/Makefile.lib                         | 24 ++++++++++++--

>  6 files changed, 67 insertions(+), 5 deletions(-)

>  create mode 100644 Documentation/devicetree/bindings/.gitignore

>  create mode 100644 Documentation/devicetree/bindings/Makefile

>

> 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..d9194c02dd08

> --- /dev/null

> +++ b/Documentation/devicetree/bindings/.gitignore

> @@ -0,0 +1 @@

> +*.example.dts

> diff --git a/Documentation/devicetree/bindings/Makefile b/Documentation/devicetree/bindings/Makefile

> new file mode 100644

> index 000000000000..ee0110dd8131

> --- /dev/null

> +++ b/Documentation/devicetree/bindings/Makefile

> @@ -0,0 +1,33 @@

> +# 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   $<

> +      cmd_chk_binding = (set -e; \

> +                         $(DT_DOC_CHECKER) $< ; \

> +                         mkdir -p $(dir $@) ; \

> +                         $(DT_EXTRACT_EX) $< > $@ )

> +

> +$(obj)/%.example.dts: $(src)/%.yaml FORCE

> +       $(call if_changed,chk_binding)

> +

> +DT_TMP_SCHEMA := .schema.yaml.tmp

> +extra-y += $(DT_TMP_SCHEMA)

> +

> +quiet_cmd_mk_schema = SCHEMA  $@

> +      cmd_mk_schema = mkdir -p $(obj); \

> +                      rm -f $@; \

> +                      $(DT_MK_SCHEMA) $(DT_MK_SCHEMA_FLAGS) -o $@ $<



I think '$<' is wrong.

'$<' is replaced with the first prerequisite.


You can easily check what is happening here.

$ cat   Documentation/devicetree/bindings/..schema.yaml.tmp.cmd
cmd_Documentation/devicetree/bindings/.schema.yaml.tmp := mkdir -p
Documentation/devicetree/bindings; rm -f
Documentation/devicetree/bindings/.schema.yaml.tmp; dt-mk-schema  -o
Documentation/devicetree/bindings/.schema.yaml.tmp
Documentation/devicetree/bindings/arm/ti/ti,davinci.yaml


So, the dt-validater will check only binding from ti,davinci.yaml,
which is almost useless.



If I understand it correctly,
.schema.yaml.tmp should contain all binding yaml.


I fixed it up like follows:

diff --git a/Documentation/devicetree/bindings/Makefile
b/Documentation/devicetree/bindings/Makefile
index ee0110d..267458f 100644
--- a/Documentation/devicetree/bindings/Makefile
+++ b/Documentation/devicetree/bindings/Makefile
@@ -19,7 +19,7 @@ extra-y += $(DT_TMP_SCHEMA)
 quiet_cmd_mk_schema = SCHEMA  $@
       cmd_mk_schema = mkdir -p $(obj); \
                       rm -f $@; \
-                      $(DT_MK_SCHEMA) $(DT_MK_SCHEMA_FLAGS) -o $@ $<
+                      $(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))



Then, I see another error.


  SCHEMA  Documentation/devicetree/bindings/.schema.yaml.tmp
Traceback (most recent call last):
  File "/home/masahiro/ref/yaml-bindings/tools/dt-mk-schema", line 32,
in <module>
    schemas = dtschema.process_schemas(args.schemas, core_schema=(not
args.useronly))
  File "/usr/local/lib/python3.5/dist-packages/dtschema-0.0.1-py3.5.egg/dtschema/lib.py",
line 359, in process_schemas
    sch = process_schema(os.path.abspath(filename))
  File "/usr/local/lib/python3.5/dist-packages/dtschema-0.0.1-py3.5.egg/dtschema/lib.py",
line 314, in process_schema
    schema = load_schema(filename)
  File "/usr/local/lib/python3.5/dist-packages/dtschema-0.0.1-py3.5.egg/dtschema/lib.py",
line 80, in load_schema
    return yaml.load(f.read())
  File "/usr/lib/python3.5/codecs.py", line 321, in decode
    (result, consumed) = self._buffer_decode(data, self.errors, final)
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xd0 in position
0: invalid continuation byte
Documentation/devicetree/bindings/Makefile:33: recipe for target
'Documentation/devicetree/bindings/.schema.yaml.tmp' failed
make[1]: *** [Documentation/devicetree/bindings/.schema.yaml.tmp] Error 1
Makefile:1278: recipe for target 'dt_binding_check' failed
make: *** [dt_binding_check] Error 2







BTW, I cannot build *.dt.yaml



  DTC     arch/arm/boot/dts/alpine-db.dt.yaml
FATAL ERROR: Unknown output format "yaml"
scripts/Makefile.lib:313: recipe for target
'arch/arm/boot/dts/alpine-db.dt.yaml' failed
make[1]: *** [arch/arm/boot/dts/alpine-db.dt.yaml] Error 1
make[1]: *** Deleting file 'arch/arm/boot/dts/alpine-db.dt.yaml'
Makefile:1262: recipe for target 'dtbs_check' failed




I use linux-next.


script/dtc/dtc does not understand '-O yaml'


I also tried the upstream DTC project with no success.


Where can I get dtc with yaml support?





-- 
Best Regards
Masahiro Yamada
Rob Herring Dec. 10, 2018, 3:55 p.m. | #2
On Fri, Dec 7, 2018 at 10:47 PM Masahiro Yamada
<yamada.masahiro@socionext.com> wrote:
>

> Hi Rob,

>

>

> On Tue, Dec 4, 2018 at 6:32 AM 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 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>

> > ---

> >  .gitignore                                   |  1 +

> >  Documentation/Makefile                       |  2 +-

> >  Documentation/devicetree/bindings/.gitignore |  1 +

> >  Documentation/devicetree/bindings/Makefile   | 33 ++++++++++++++++++++

> >  Makefile                                     | 11 +++++--

> >  scripts/Makefile.lib                         | 24 ++++++++++++--

> >  6 files changed, 67 insertions(+), 5 deletions(-)

> >  create mode 100644 Documentation/devicetree/bindings/.gitignore

> >  create mode 100644 Documentation/devicetree/bindings/Makefile

> >

> > 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..d9194c02dd08

> > --- /dev/null

> > +++ b/Documentation/devicetree/bindings/.gitignore

> > @@ -0,0 +1 @@

> > +*.example.dts

> > diff --git a/Documentation/devicetree/bindings/Makefile b/Documentation/devicetree/bindings/Makefile

> > new file mode 100644

> > index 000000000000..ee0110dd8131

> > --- /dev/null

> > +++ b/Documentation/devicetree/bindings/Makefile

> > @@ -0,0 +1,33 @@

> > +# 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   $<

> > +      cmd_chk_binding = (set -e; \

> > +                         $(DT_DOC_CHECKER) $< ; \

> > +                         mkdir -p $(dir $@) ; \

> > +                         $(DT_EXTRACT_EX) $< > $@ )

> > +

> > +$(obj)/%.example.dts: $(src)/%.yaml FORCE

> > +       $(call if_changed,chk_binding)

> > +

> > +DT_TMP_SCHEMA := .schema.yaml.tmp

> > +extra-y += $(DT_TMP_SCHEMA)

> > +

> > +quiet_cmd_mk_schema = SCHEMA  $@

> > +      cmd_mk_schema = mkdir -p $(obj); \

> > +                      rm -f $@; \

> > +                      $(DT_MK_SCHEMA) $(DT_MK_SCHEMA_FLAGS) -o $@ $<

>

>

> I think '$<' is wrong.

>

> '$<' is replaced with the first prerequisite.


Indeed.

> You can easily check what is happening here.

>

> $ cat   Documentation/devicetree/bindings/..schema.yaml.tmp.cmd

> cmd_Documentation/devicetree/bindings/.schema.yaml.tmp := mkdir -p

> Documentation/devicetree/bindings; rm -f

> Documentation/devicetree/bindings/.schema.yaml.tmp; dt-mk-schema  -o

> Documentation/devicetree/bindings/.schema.yaml.tmp

> Documentation/devicetree/bindings/arm/ti/ti,davinci.yaml

>

>

> So, the dt-validater will check only binding from ti,davinci.yaml,

> which is almost useless.

>

>

>

> If I understand it correctly,

> .schema.yaml.tmp should contain all binding yaml.

>

>

> I fixed it up like follows:

>

> diff --git a/Documentation/devicetree/bindings/Makefile

> b/Documentation/devicetree/bindings/Makefile

> index ee0110d..267458f 100644

> --- a/Documentation/devicetree/bindings/Makefile

> +++ b/Documentation/devicetree/bindings/Makefile

> @@ -19,7 +19,7 @@ extra-y += $(DT_TMP_SCHEMA)

>  quiet_cmd_mk_schema = SCHEMA  $@

>        cmd_mk_schema = mkdir -p $(obj); \

>                        rm -f $@; \

> -                      $(DT_MK_SCHEMA) $(DT_MK_SCHEMA_FLAGS) -o $@ $<

> +                      $(DT_MK_SCHEMA) $(DT_MK_SCHEMA_FLAGS) -o $@

> $(filter-out FORCE, $^)


Thanks, I incorporated this fix.

>

>  DT_DOCS = $(shell cd $(srctree)/$(src) && find * -name '*.yaml')

>  DT_SCHEMA_FILES ?= $(addprefix $(src)/,$(DT_DOCS))

>

>

>

> Then, I see another error.


I fixed this with this change:

@@ -27,7 +27,7 @@ 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): $(addprefix $(obj)/,$(patsubst
$(src)/%.yaml,%.example.dtb, $(DT_SCHEMA_FILES)))
+$(obj)/$(DT_TMP_SCHEMA): | $(addprefix $(obj)/,$(patsubst
$(src)/%.yaml,%.example.dtb, $(DT_SCHEMA_FILES)))

 $(obj)/$(DT_TMP_SCHEMA): $(addprefix $(srctree)/, $(DT_SCHEMA_FILES)) FORCE
        $(call if_changed,mk_schema)

>

>

>   SCHEMA  Documentation/devicetree/bindings/.schema.yaml.tmp

> Traceback (most recent call last):

>   File "/home/masahiro/ref/yaml-bindings/tools/dt-mk-schema", line 32,

> in <module>

>     schemas = dtschema.process_schemas(args.schemas, core_schema=(not

> args.useronly))

>   File "/usr/local/lib/python3.5/dist-packages/dtschema-0.0.1-py3.5.egg/dtschema/lib.py",

> line 359, in process_schemas

>     sch = process_schema(os.path.abspath(filename))

>   File "/usr/local/lib/python3.5/dist-packages/dtschema-0.0.1-py3.5.egg/dtschema/lib.py",

> line 314, in process_schema

>     schema = load_schema(filename)

>   File "/usr/local/lib/python3.5/dist-packages/dtschema-0.0.1-py3.5.egg/dtschema/lib.py",

> line 80, in load_schema

>     return yaml.load(f.read())

>   File "/usr/lib/python3.5/codecs.py", line 321, in decode

>     (result, consumed) = self._buffer_decode(data, self.errors, final)

> UnicodeDecodeError: 'utf-8' codec can't decode byte 0xd0 in position

> 0: invalid continuation byte

> Documentation/devicetree/bindings/Makefile:33: recipe for target

> 'Documentation/devicetree/bindings/.schema.yaml.tmp' failed

> make[1]: *** [Documentation/devicetree/bindings/.schema.yaml.tmp] Error 1

> Makefile:1278: recipe for target 'dt_binding_check' failed

> make: *** [dt_binding_check] Error 2

>

>

>

>

>

>

>

> BTW, I cannot build *.dt.yaml

>

>

>

>   DTC     arch/arm/boot/dts/alpine-db.dt.yaml

> FATAL ERROR: Unknown output format "yaml"

> scripts/Makefile.lib:313: recipe for target

> 'arch/arm/boot/dts/alpine-db.dt.yaml' failed

> make[1]: *** [arch/arm/boot/dts/alpine-db.dt.yaml] Error 1

> make[1]: *** Deleting file 'arch/arm/boot/dts/alpine-db.dt.yaml'

> Makefile:1262: recipe for target 'dtbs_check' failed

>

>

>

>

> I use linux-next.

>

>

> script/dtc/dtc does not understand '-O yaml'

>

>

> I also tried the upstream DTC project with no success.

>

>

> Where can I get dtc with yaml support?


You need libyaml and its headers. I'll try to make this a better error
message. For now, libyaml is optional so we don't break everyone just
building dtbs.

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..d9194c02dd08
--- /dev/null
+++ b/Documentation/devicetree/bindings/.gitignore
@@ -0,0 +1 @@ 
+*.example.dts
diff --git a/Documentation/devicetree/bindings/Makefile b/Documentation/devicetree/bindings/Makefile
new file mode 100644
index 000000000000..ee0110dd8131
--- /dev/null
+++ b/Documentation/devicetree/bindings/Makefile
@@ -0,0 +1,33 @@ 
+# 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   $<
+      cmd_chk_binding = (set -e; \
+                         $(DT_DOC_CHECKER) $< ; \
+                         mkdir -p $(dir $@) ; \
+                         $(DT_EXTRACT_EX) $< > $@ )
+
+$(obj)/%.example.dts: $(src)/%.yaml FORCE
+	$(call if_changed,chk_binding)
+
+DT_TMP_SCHEMA := .schema.yaml.tmp
+extra-y += $(DT_TMP_SCHEMA)
+
+quiet_cmd_mk_schema = SCHEMA  $@
+      cmd_mk_schema = mkdir -p $(obj); \
+                      rm -f $@; \
+                      $(DT_MK_SCHEMA) $(DT_MK_SCHEMA_FLAGS) -o $@ $<
+
+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): $(addprefix $(obj)/,$(patsubst $(src)/%.yaml,%.example.dtb, $(DT_SCHEMA_FILES)))
+
+$(obj)/$(DT_TMP_SCHEMA): $(addprefix $(srctree)/, $(DT_SCHEMA_FILES)) FORCE
+	$(call if_changed,mk_schema)
diff --git a/Makefile b/Makefile
index 2f36db897895..ff59adf43300 100644
--- a/Makefile
+++ b/Makefile
@@ -1232,10 +1232,13 @@  ifneq ($(dtstree),)
 %.dtb: prepare3 scripts_dtc
 	$(Q)$(MAKE) $(build)=$(dtstree) $(dtstree)/$@
 
-PHONY += dtbs dtbs_install
+PHONY += dtbs dtbs_install dt_binding_check
 dtbs: prepare3 scripts_dtc
 	$(Q)$(MAKE) $(build)=$(dtstree)
 
+dtbs_check: prepare3 dt_binding_check
+	$(Q)$(MAKE) $(build)=$(dtstree) CHECK_DTBS=1
+
 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..d1c5630ba24c 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)/.schema.yaml.tmp
+
+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)