All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] dt: Add a check for undocumented compatible strings in kernel
@ 2022-09-16  1:25 Rob Herring
  0 siblings, 0 replies; only message in thread
From: Rob Herring @ 2022-09-16  1:25 UTC (permalink / raw)
  To: Krzysztof Kozlowski, Masahiro Yamada, Michal Marek,
	Nick Desaulniers, Frank Rowand
  Cc: devicetree, linux-kernel, linux-kbuild

Add a make target, dt_compatible_check, to extract compatible strings
from kernel sources and check if they are documented by a schema.
At least version v2022.08 of dtschema with dt-check-compatible is
required.

This check can also be run manually on specific files or directories:

scripts/dtc/dt-extract-compatibles drivers/clk/ | \
  xargs dt-check-compatible -v -s Documentation/devicetree/bindings/processed-schema.json

Currently, there are about 3800 undocumented compatible strings. Most of
these are cases where the binding is not yet converted (given there
are 1900 .txt binding files remaining).

Signed-off-by: Rob Herring <robh@kernel.org>
---
 Documentation/devicetree/bindings/Makefile |  3 +
 Makefile                                   |  4 ++
 scripts/dtc/dt-extract-compatibles         | 68 ++++++++++++++++++++++
 3 files changed, 75 insertions(+)
 create mode 100755 scripts/dtc/dt-extract-compatibles

diff --git a/Documentation/devicetree/bindings/Makefile b/Documentation/devicetree/bindings/Makefile
index 1eaccf135b30..bf2d8a8ced77 100644
--- a/Documentation/devicetree/bindings/Makefile
+++ b/Documentation/devicetree/bindings/Makefile
@@ -75,3 +75,6 @@ always-$(CHECK_DT_BINDING) += $(patsubst $(srctree)/$(src)/%.yaml,%.example.dtb,
 # build artifacts here before they are processed by scripts/Makefile.clean
 clean-files = $(shell find $(obj) \( -name '*.example.dts' -o \
 			-name '*.example.dtb' \) -delete 2>/dev/null)
+
+dt_compatible_check: $(obj)/processed-schema.json
+	$(Q)$(srctree)/scripts/dtc/dt-extract-compatibles $(srctree) | xargs dt-check-compatible -v -s $<
diff --git a/Makefile b/Makefile
index f09673b6c11d..7f19e1725b2f 100644
--- a/Makefile
+++ b/Makefile
@@ -1419,6 +1419,10 @@ PHONY += dt_binding_check
 dt_binding_check: scripts_dtc
 	$(Q)$(MAKE) $(build)=Documentation/devicetree/bindings
 
+PHONY += dt_compatible_check
+dt_compatible_check: dt_binding_check
+	$(Q)$(MAKE) $(build)=Documentation/devicetree/bindings $@
+
 # ---------------------------------------------------------------------------
 # Modules
 
diff --git a/scripts/dtc/dt-extract-compatibles b/scripts/dtc/dt-extract-compatibles
new file mode 100755
index 000000000000..3a6dd3c40ac1
--- /dev/null
+++ b/scripts/dtc/dt-extract-compatibles
@@ -0,0 +1,68 @@
+#!/usr/bin/env python3
+# SPDX-License-Identifier: GPL-2.0-only
+
+import os
+import glob
+import re
+import argparse
+
+
+def parse_of_declare_macros(data):
+	""" Find all compatible strings in OF_DECLARE() style macros """
+	compat_list = []
+	for m in re.finditer(r'(IRQCHIP|OF)_(DECLARE|MATCH)(_DRIVER)?\(.*?\)', data):
+		try:
+			compat = re.search(r'"(.*?)"', m[0])[1]
+		except:
+			# Fails on compatible strings in #define, so just skip
+			continue
+		compat_list += [compat]
+
+	return compat_list
+
+
+def parse_of_device_id(data):
+	""" Find all compatible strings in of_device_id structs """
+	compat_list = []
+	for m in re.finditer(r'of_device_id\s+[a-zA-Z0-9_]+\[\]\s*=\s*({.*?);', data):
+		compat_list += re.findall(r'\.compatible\s+=\s+"([a-zA-Z0-9_\-,]+)"', m[1])
+
+	return compat_list
+
+
+def parse_compatibles(file):
+	with open(file, 'r', encoding='utf-8') as f:
+		data = f.read().replace('\n', '')
+
+	compat_list = parse_of_declare_macros(data)
+	compat_list += parse_of_device_id(data)
+
+	return compat_list
+
+def print_compat(filename, compatibles):
+	if not compatibles:
+		return
+	if show_filename:
+		compat_str = ' '.join(compatibles)
+		print(filename + ": compatible(s): " + compat_str)
+	else:
+		print(*compatibles, sep='\n')
+
+show_filename = False
+
+if __name__ == "__main__":
+	ap = argparse.ArgumentParser()
+	ap.add_argument("cfile", type=str, nargs='*', help="C source files or directories to parse")
+	ap.add_argument('-H', '--with-filename', help="Print filename with compatibles", action="store_true")
+	args = ap.parse_args()
+
+	show_filename = args.with_filename
+
+	for f in args.cfile:
+		if os.path.isdir(f):
+			for filename in glob.iglob(f + "/**/*.c", recursive=True):
+				compat_list = parse_compatibles(filename)
+				print_compat(filename, compat_list)
+		else:
+			compat_list = parse_compatibles(f)
+			print_compat(f, compat_list)
-- 
2.34.1


^ permalink raw reply related	[flat|nested] only message in thread

only message in thread, other threads:[~2022-09-16  1:25 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-09-16  1:25 [PATCH] dt: Add a check for undocumented compatible strings in kernel Rob Herring

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.