PHONY += dtbs dtbs_prepare dtbs_install dtbs_check
 dtbs: dtbs_prepare
-       $(Q)$(MAKE) $(build)=$(dtstree)
+       $(Q)$(MAKE) $(build)=$(dtstree) need-dtbslist=1
 
 # include/config/kernel.release is actually needed when installing DTBs because
 # INSTALL_DTBS_PATH contains $(KERNELRELEASE). However, we do not want to make
                -o -name '*.ko.*' \
                -o -name '*.dtb' -o -name '*.dtbo' \
                -o -name '*.dtb.S' -o -name '*.dtbo.S' \
-               -o -name '*.dt.yaml' \
+               -o -name '*.dt.yaml' -o -name 'dtbs-list' \
                -o -name '*.dwo' -o -name '*.lst' \
                -o -name '*.su' -o -name '*.mod' \
                -o -name '.*.d' -o -name '.*.tmp' -o -name '*.mod.c' \
 
 # subdir-builtin and subdir-modorder may contain duplications. Use $(sort ...)
 subdir-builtin := $(sort $(filter %/built-in.a, $(real-obj-y)))
 subdir-modorder := $(sort $(filter %/modules.order, $(obj-m)))
+subdir-dtbslist := $(sort $(filter %/dtbs-list, $(dtb-y)))
 
 targets-for-builtin := $(extra-y)
 
 # To build objects in subdirs, we need to descend into the directories
 $(subdir-builtin): $(obj)/%/built-in.a: $(obj)/% ;
 $(subdir-modorder): $(obj)/%/modules.order: $(obj)/% ;
+$(subdir-dtbslist): $(obj)/%/dtbs-list: $(obj)/% ;
 
 #
 # Rule to compile a set of .o files into one .a file (without symbol table)
        $(call if_changed,ar_builtin)
 
 #
-# Rule to create modules.order file
+# Rule to create modules.order and dtbs-list
 #
-# Create commands to either record .ko file or cat modules.order from
-# a subdirectory
-# Add $(obj-m) as the prerequisite to avoid updating the timestamp of
-# modules.order unless contained modules are updated.
+# This is a list of build artifacts (module or dtb) from the current Makefile
+# and its sub-directories. The timestamp should be updated when any of the
+# member files.
 
-cmd_modules_order = { $(foreach m, $(real-prereqs), \
-       $(if $(filter %/modules.order, $m), cat $m, echo $m);) :; } \
+cmd_gen_order = { $(foreach m, $(real-prereqs), \
+       $(if $(filter %/$(notdir $@), $m), cat $m, echo $m);) :; } \
        > $@
 
 $(obj)/modules.order: $(obj-m) FORCE
-       $(call if_changed,modules_order)
+       $(call if_changed,gen_order)
+
+$(obj)/dtbs-list: $(dtb-y) FORCE
+       $(call if_changed,gen_order)
 
 #
 # Rule to compile a set of .o files into one .a file (with symbol table)
 
 obj-y          := $(filter-out %/, $(obj-y))
 endif
 
+ifdef need-dtbslist
+dtb-y          += $(addsuffix /dtbs-list, $(subdir-ym))
+always-y       += dtbs-list
+endif
+
 # Expand $(foo-objs) $(foo-y) etc. by replacing their individuals
 suffix-search = $(strip $(foreach s, $3, $($(1:%$(strip $2)=%$s))))
 # List composite targets that are constructed by combining other targets
 real-obj-y     := $(addprefix $(obj)/,$(real-obj-y))
 real-obj-m     := $(addprefix $(obj)/,$(real-obj-m))
 multi-obj-m    := $(addprefix $(obj)/, $(multi-obj-m))
+dtb-y          := $(addprefix $(obj)/, $(dtb-y))
 multi-dtb-y    := $(addprefix $(obj)/, $(multi-dtb-y))
 real-dtb-y     := $(addprefix $(obj)/, $(real-dtb-y))
 subdir-ym      := $(addprefix $(obj)/,$(subdir-ym))