pax_global_header00006660000000000000000000000064150441456300014514gustar00rootroot0000000000000052 comment=48fd9bbd32632ae56930e9c620f146986cc1a9f8 dt-schema-2025.08/000077500000000000000000000000001504414563000135415ustar00rootroot00000000000000dt-schema-2025.08/.github/000077500000000000000000000000001504414563000151015ustar00rootroot00000000000000dt-schema-2025.08/.github/workflows/000077500000000000000000000000001504414563000171365ustar00rootroot00000000000000dt-schema-2025.08/.github/workflows/ci.yml000066400000000000000000000020251504414563000202530ustar00rootroot00000000000000 on: [push, pull_request] jobs: build: runs-on: ubuntu-latest strategy: fail-fast: false matrix: python-version: ['3.8', '3.9', '3.10', '3.11', '3.12', '3.13'] steps: - uses: actions/checkout@v4 - name: Set up Python ${{ matrix.python-version }} uses: actions/setup-python@v5 with: python-version: ${{ matrix.python-version }} - name: Install dependencies run: | sudo apt-get -qq -y install device-tree-compiler python -m pip install --upgrade pip python -m pip install flake8 python -m pip install . - name: Lint with flake8 run: | # stop the build if there are Python syntax errors or undefined names flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics # exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics - name: Test run: | test/test-dt-validate.py dt-schema-2025.08/.github/workflows/publish.yml000066400000000000000000000011371504414563000213310ustar00rootroot00000000000000name: Upload Python Package on: push: tags: - 'v*' - '!v*-pre' jobs: deploy: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - name: Set up Python uses: actions/setup-python@v2 with: python-version: '3.x' - name: Install dependencies run: | python -m pip install --upgrade pip pip install build - name: Build package run: python -m build - name: Publish package uses: pypa/gh-action-pypi-publish@release/v1 with: user: __token__ password: ${{ secrets.PYPI_API_TOKEN }} dt-schema-2025.08/.gitignore000066400000000000000000000000571504414563000155330ustar00rootroot00000000000000.eggs __pycache__ build dist dtschema.egg-info dt-schema-2025.08/LICENSE.txt000066400000000000000000000024221504414563000153640ustar00rootroot00000000000000Copyright 2018-2019 Linaro Ltd. Copyright 2018-2020 Arm Ltd. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. dt-schema-2025.08/README.md000066400000000000000000000131421504414563000150210ustar00rootroot00000000000000# Devicetree Schema Tools The dtschema module contains tools and schema data for Devicetree schema validation using the [json-schema](https://json-schema.org) vocabulary. The tools validate Devicetree files using DT binding schema files. The tools also validate the DT binding schema files. Schema files are written in a JSON compatible subset of YAML to be both human and machine readable. ## Data Model To understand how validation works, it is important to understand how schema data is organized and used. If you're reading this, I assume you're already familiar with Devicetree and the .dts file format. In this repository you will find 2 kinds of data files; *Schemas* and *Meta-Schemas*. ### *Devicetree Schemas* Found under `./dtschema/schemas` *Devicetree Schemas* describe the format of devicetree data. The raw Devicetree file format is very open ended and doesn't restrict how data is encoded.Hence, it is easy to make mistakes when writing a Devicetree. Schema files impose the constraints on what data can be put into a Devicetree. This repository contains the 'core' schemas which consists of DT properties defined within the DT Specification and common bindings such as the GPIO, clock, and PHY bindings. This repository does not contain device specific bindings. Those are currently maintained within the Linux kernel tree alongside Devicetree files (.dts). When validating, the tool will load all the schema files it can find and then iterate over all the nodes of the Devicetree. For each node, the tool will determine which schema(s) are applicable and make sure the node data matches the schema constraints. Nodes failing a schema test will emit an error. Nodes that don't match any schema can emit a warning. As a developer, you would write a Devicetree schema file for each new device binding that you create and add it to the `./schemas` directory. Schema files also have the dual purpose of documenting a binding. When you define a new binding, you only have to create one file that contains both the machine-verifiable data format and the documentation. Devicetree Schema files are normal YAML files using the jsonschema vocabulary. The Devicetree Schema files are simplified to make them more compact. The default for arrays in json-schema is they are variable sized. This can be restricted by defining 'minItems', 'maxItems', and 'additionalItems'. For DeviceTree Schemas, a fixed size is desired in most cases, so these properties are added based on the size of 'items' list. ### *Devicetree Meta-Schemas* Found in `./dtschema/meta-schemas` *Devicetree Meta-Schemas* describe the data format of Devicetree Schema files. The Meta-schemas make sure all the binding schemas are in the correct format and the tool will emit an error if the format is incorrect. json-schema by default is very relaxed in terms of what is allowed in schemas. Unknown keywords are silently ignored as an example. The DT Meta-schemas are designed to limit what is allowed and catch common errors in writing schemas. As a developer you normally will not need to write metaschema files. Devicetree Meta-Schema files are normal YAML files using the jsonschema vocabulary. ## Usage There are several tools available in the *tools/* directory. `tools/dt-doc-validate` This tool takes a schema file(s) or directory of schema files and validates them against the DT meta-schema. Example: ``` dt-doc-validate -u test/schemas test/schemas/good-example.yaml ``` `tools/dt-mk-schema` This tool takes user-provided schema file(s) plus the core schema files in this repo, removes everything not needed for validation, applies fix-ups to the schemas, and outputs a single file with the processed schema. This step is optional and can be done separately to speed up subsequent validation of Devicetrees. Example: ``` dt-mk-schema -j test/schemas/ > processed-schema.json ``` `tools/dt-validate` This tool takes user-provided Devicetree(s) and either a schema directory or a pre-processed schema file from `dt-mk-schema`, and then validates the Devicetree against the schema. Example: ``` dtc -O dtb -o device.dtb test/device.dts dt-validate -s processed-schema.json device.dtb ``` `tools/dt-check-compatible` This tool tests whether a list of compatible strings are found or not in the schemas. By default, a compatible string is printed when it matches one (or a pattern) in the schemas. Example: ``` dt-check-compatible -s processed-schema.json vendor,a-compatible ``` ## Installing The project and its dependencies can be installed with pip: ``` pip3 install dtschema ``` or directly from git: ``` pip3 install git+https://github.com/devicetree-org/dt-schema.git@main ``` All executables will be installed. Ensure ~/.local/bin is in the PATH. For development, clone the git repository manually and run pip on local tree:: ``` git clone https://github.com/devicetree-org/dt-schema.git cd dt-schema pip3 install -e . ``` ## Dependencies Note: The above installation instructions handle all of the dependencies automatically. This code depends on Python 3 with the pylibfdt, ruamel.yaml, rfc3987, and jsonschema libraries. Installing pylibfdt depends on the 'swig' program. On Debian/Ubuntu, the dependencies can be installed with apt and/or pip. The rfc3987 module is not packaged, so pip must be used: ``` sudo apt install swig sudo apt install python3 python3-ruamel.yaml pip3 install rfc3987 ``` ### jsonschema This code depends on at least version 4.1.2 of the [Python jsonschema](https://github.com/Julian/jsonschema/tree/master) library for Draft 2019-09 support. The module can be installed directly from github with pip: ``` pip3 install git+https://github.com/Julian/jsonschema.git ``` dt-schema-2025.08/dtschema/000077500000000000000000000000001504414563000153315ustar00rootroot00000000000000dt-schema-2025.08/dtschema/.gitignore000066400000000000000000000000131504414563000173130ustar00rootroot00000000000000version.py dt-schema-2025.08/dtschema/__init__.py000066400000000000000000000010211504414563000174340ustar00rootroot00000000000000import signal import sys def sigint_handler(signum, frame): sys.exit(-2) signal.signal(signal.SIGINT, sigint_handler) from dtschema.lib import ( format_error, extract_compatibles, extract_node_compatibles, _is_int_schema, _is_string_schema, _get_array_range, sized_int, ) from dtschema.fixups import ( fixup_schema, ) from dtschema.schema import ( DTSchema, ) from dtschema.validator import ( DTValidator, ) from dtschema.version import ( __version__ ) import dtschema.dtb dt-schema-2025.08/dtschema/check_compatible.py000077500000000000000000000027731504414563000211730ustar00rootroot00000000000000#!/usr/bin/env python3 # SPDX-License-Identifier: BSD-2-Clause # Copyright 2022 Arm Ltd. import os import argparse import dtschema def main(): ap = argparse.ArgumentParser(fromfile_prefix_chars='@', epilog='Arguments can also be passed in a file prefixed with a "@" character.') ap.add_argument("compatible_str", nargs='+', help="1 or more compatible strings to check for a match") ap.add_argument('-q', '--quiet', action="store_true", help="Suppress printing matches") ap.add_argument('-v', '--invert-match', action="store_true", help="invert sense of matching, printing compatible which don't match") ap.add_argument('-V', '--version', help="Print version number", action="version", version=dtschema.__version__) ap.add_argument('-s', '--schema', required=True, help="path to processed schema file or schema directory") args = ap.parse_args() if args.schema != "" and not os.path.exists(args.schema): exit(-1) undoc_compats = dtschema.DTValidator([args.schema]).get_undocumented_compatibles(args.compatible_str) if args.invert_match: if len(undoc_compats) > 0: if not args.quiet: print(*undoc_compats, sep="\n") return 0 else: matches = set(args.compatible_str).difference(undoc_compats) if len(matches) > 0: if not args.quiet: print(*matches, sep="\n") return 0 return -1 dt-schema-2025.08/dtschema/cmp_schema.py000077500000000000000000000111261504414563000200060ustar00rootroot00000000000000#!/usr/bin/env python3 # SPDX-License-Identifier: BSD-2-Clause # Copyright 2023-2024 Arm Ltd. import sys import argparse import urllib import dtschema def path_list_to_str(path): return '/' + '/'.join(path) def prop_generator(schema, path=[]): if not isinstance(schema, dict): return for prop_key in ['properties', 'patternProperties']: if prop_key in schema: for p, sch in schema[prop_key].items(): yield path + [prop_key, p], sch yield from prop_generator(sch, path=path + [prop_key, p]) def _ref_to_id(schema_id, ref): ref = urllib.parse.urljoin(schema_id, ref) if '#/' not in ref: ref += '#' return ref def _prop_in_schema(prop, schema, schemas): for p, sch in prop_generator(schema): if p[1] == prop: return True if 'allOf' in schema: for e in schema['allOf']: if '$ref' in e: ref_id = _ref_to_id(schema['$id'], e['$ref']) if ref_id in schemas: if _prop_in_schema(prop, schemas[ref_id], schemas): return True if '$ref' in schema: ref_id = _ref_to_id(schema['$id'], schema['$ref']) if ref_id in schemas and _prop_in_schema(prop, schemas[ref_id], schemas): return True return False def check_removed_property(schema_id, base, schemas): for p, sch in prop_generator(base): if not _prop_in_schema(p[1], schemas[schema_id], schemas): print(f'{schema_id}{path_list_to_str(p)}: existing property removed', file=sys.stderr) def check_deprecated_property(schema_id, base, schemas): for p, sch in prop_generator(base): if isinstance(sch, dict) and 'deprecated' in sch: continue schema = schema_get_from_path(schemas[schema_id], p) if schema and isinstance(schema, dict) and 'deprecated' in schema: print(f'{schema_id}{path_list_to_str(p)}: existing property deprecated', file=sys.stderr) def schema_get_from_path(sch, path): for p in path: try: sch = sch[p] except: return None return sch def check_new_items(schema_id, base, new): for p, sch in prop_generator(new): if not isinstance(sch, dict) or 'minItems' not in sch: continue new_min = sch['minItems'] base_min = schema_get_from_path(base, p + ['minItems']) if base_min and new_min > base_min: print(f'{schema_id}{path_list_to_str(p)}: required entries increased from {base_min} to {new_min}', file=sys.stderr) def _get_required(schema): required = [] for k in {'allOf', 'oneOf', 'anyOf'} & schema.keys(): for sch in schema[k]: if 'required' not in sch: continue required += sch['required'] if 'required' in schema: required += schema['required'] return set(required) def _check_required(schema_id, base, new, path=[]): if not isinstance(base, dict) or not isinstance(new, dict): return base_req = _get_required(base) new_req = _get_required(new) if not new_req: return diff = new_req - base_req if diff: print(f'{schema_id}{path_list_to_str(path)}: new required properties added: {", ".join(diff)}', file=sys.stderr) return def check_required(schema_id, base, new): _check_required(schema_id, base, new) for p, sch in prop_generator(new): _check_required(schema_id, schema_get_from_path(base, p), sch, path=p) def main(): ap = argparse.ArgumentParser(description="Compare 2 sets of schemas for possible ABI differences") ap.add_argument("baseline", type=str, help="Baseline schema directory or preprocessed schema file") ap.add_argument("new", type=str, help="New schema directory or preprocessed schema file") ap.add_argument('-V', '--version', help="Print version number", action="version", version=dtschema.__version__) args = ap.parse_args() base_schemas = dtschema.DTValidator([args.baseline]).schemas schemas = dtschema.DTValidator([args.new]).schemas if not schemas or not base_schemas: return -1 for schema_id, sch in schemas.items(): if schema_id not in base_schemas or 'generated' in schema_id: continue check_required(schema_id, base_schemas[schema_id], sch) check_removed_property(schema_id, base_schemas[schema_id], schemas) check_deprecated_property(schema_id, base_schemas[schema_id], schemas) check_new_items(schema_id, base_schemas[schema_id], sch) dt-schema-2025.08/dtschema/doc_validate.py000077500000000000000000000037541504414563000203350ustar00rootroot00000000000000#!/usr/bin/env python3 # SPDX-License-Identifier: BSD-2-Clause # Copyright 2018 Linaro Ltd. # Copyright 2018 Arm Ltd. import os import sys import argparse import glob import ruamel.yaml import dtschema line_number = False verbose = False def check_doc(filename): ret = 0 try: dtsch = dtschema.DTSchema(filename, line_numbers=line_number) except ruamel.yaml.YAMLError as exc: print(filename + ":" + str(exc.problem_mark.line + 1) + ":" + str(exc.problem_mark.column + 1) + ":", exc.problem, file=sys.stderr) return 1 try: for error in sorted(dtsch.iter_errors(), key=lambda e: e.linecol): print(dtschema.format_error(filename, error, verbose=verbose), file=sys.stderr) ret = 1 except: raise print(filename + ': error checking schema file', file=sys.stderr) return 1 dtsch.check_schema_refs() return ret def main(): global verbose global line_number ap = argparse.ArgumentParser(fromfile_prefix_chars='@', epilog='Arguments can also be passed in a file prefixed with a "@" character.') ap.add_argument("yamldt", nargs='*', type=str, help="Directory or filename of YAML encoded devicetree schema file") ap.add_argument('-v', '--verbose', help="verbose mode", action="store_true") ap.add_argument('-n', '--line-number', help="Print line and column numbers (slower)", action="store_true") ap.add_argument('-u', '--url-path', help="Additional search path for references") ap.add_argument('-V', '--version', help="Print version number", action="version", version=dtschema.__version__) args = ap.parse_args() line_number = args.line_number verbose = args.verbose ret = 0 for f in args.yamldt: if os.path.isdir(f): for filename in glob.iglob(f + "/**/*.yaml", recursive=True): ret |= check_doc(filename) else: ret |= check_doc(f) exit(ret) dt-schema-2025.08/dtschema/dtb.py000066400000000000000000000420151504414563000164560ustar00rootroot00000000000000# SPDX-License-Identifier: BSD-2-Clause # Copyright 2021-2022 Arm Ltd. # Python library for Devicetree schema validation import sys import struct import libfdt from libfdt import QUIET_NOTFOUND import dtschema u8 = struct.Struct('B') s8 = struct.Struct('b') u16 = struct.Struct('>H') s16 = struct.Struct('>h') u32 = struct.Struct('>L') s32 = struct.Struct('>l') u64 = struct.Struct('>Q') s64 = struct.Struct('>q') type_format = { 'int8': s8, 'uint8': u8, 'int16': s16, 'uint16': u16, 'int32': s32, 'uint32': u32, 'int64': s64, 'uint64': u64, 'phandle': u32, 'address': u32 } def bytes_to_string(b): try: strings = b.decode(encoding='ascii').split('\0') count = len(strings) - 1 if count > 0 and not len(strings[-1]): for string in strings[:-1]: if not string: # While empty strings are valid, assume empty strings means # not a string as we only get here when there are multiple # types. break if not string.isprintable(): break else: return strings[:-1] except: return None def get_stride(prop_len, dim): # If multiple dimensions, check if one and only one dimension fits match = [] for outer in range(dim[0][0], dim[0][1] + 1): for inner in range(dim[1][0], dim[1][1] + 1): if outer * inner == prop_len: match += [inner] if len(match) > 0: return match[0] if dim[1][0] > 0 and dim[1][0] == dim[1][1]: return dim[1][0] if dim[0][0] > 0 and dim[0][0] == dim[0][1]: return int(prop_len / dim[0][0]) return prop_len def prop_value(validator, nodename, p): # First, check for a boolean type if not len(p): return True dim = None data = bytes(p) fmt = None if nodename in {'__fixups__', 'aliases'}: return data[:-1].decode(encoding='ascii').split('\0') prop_types = set(validator.property_get_type(p.name)) prop_types -= {'node'} # Filter out types impossible for the size of the property if len(prop_types) > 1: if len(p) % 8: prop_types -= {'int64', 'uint64', 'int64-array', 'uint64-array'} if len(p) % 4: prop_types -= {'int32', 'uint32', 'int32-array', 'uint32-array', 'phandle', 'phandle-array'} if len(p) % 2: prop_types -= {'int16', 'uint16', 'int16-array', 'uint16-array'} if len(p) > 4: prop_types -= {'int32', 'uint32', 'phandle'} else: prop_types -= {'int64', 'uint64', 'int64-array', 'uint64-array'} if len(p) > 2: prop_types -= {'int16', 'uint16'} else: prop_types -= {'int32', 'uint32', 'int32-array', 'uint32-array', 'phandle', 'phandle-array'} if len(p) > 1: prop_types -= {'int8', 'uint8'} else: prop_types -= {'int16', 'uint16', 'int16-array', 'uint16-array'} if len(p) > 0: prop_types -= {'flag'} if prop_types >= {'phandle', 'phandle-array'}: prop_types -= {'phandle'} # Drop the unsigned type if both signed and unsigned type exists if prop_types >= {'int64', 'uint64'}: prop_types -= {'uint64'} if prop_types >= {'int32', 'uint32'}: prop_types -= {'uint32'} if prop_types >= {'int16', 'uint16'}: prop_types -= {'uint16'} if prop_types >= {'int8', 'uint8'}: prop_types -= {'uint8'} dim = validator.property_get_type_dim(p.name) matrix_prop_types = { t for t in prop_types if 'matrix' in t } if len(prop_types) > 1: if {'string', 'string-array'} & prop_types: str = bytes_to_string(data) if str: return str # Assuming only one other type try: fmt = prop_types.difference({'string', 'string-array'}).pop() except: return data elif matrix_prop_types: scalar_prop_types = prop_types - matrix_prop_types if len(scalar_prop_types) == 1: fmt = scalar_prop_types.pop() min_dim = dim[0][0] * dim[1][0] if len(p) / type_format[fmt].size >= min_dim: fmt = matrix_prop_types.pop() else: #print(p.name + ': multiple types found', file=sys.stderr) # HACK around type collisions. if p.name == "dma-masters": # Default for phandles, and then fixup later when we can more # reliably detect what is or isn't a phandle in fixup_handles() fmt = 'phandle-array' elif p.name == "mode-gpios": # "mode-gpios" also matches "^mode-" pattern, but it is always a GPIO fmt = 'phandle-array' else: fmt = None elif len(prop_types) == 1: fmt = prop_types.pop() if not fmt: # Primarily for aliases properties try: s = data.decode(encoding='ascii') if s.endswith('\0'): s = s[:-1] if s.isprintable(): return [s] except: pass if not len(data) % 4: fmt = 'uint32-array' else: #print(p.name + ': no type found', file=sys.stderr) return data if fmt.startswith('string'): if not data.endswith(b'\0'): # Wrong data type?, skip decoding to force errors return data return data[:-1].decode(encoding='ascii').split('\0') if {'flag'} & prop_types: if len(data): if fmt == 'flag': print('{prop}: boolean property with value {val}'.format(prop=p.name, val=data), file=sys.stderr) return data else: return True val_int = list() #print(p.name, fmt, bytes(p)) try: type_struct = type_format[fmt.split('-', 1)[0]] for i in type_struct.iter_unpack(data): val_int += [dtschema.sized_int(i[0], size=(type_struct.size * 8))] except: print('{prop}: size ({len}) error for type {fmt}'.format(prop=p.name, len=len(p), fmt=fmt), file=sys.stderr) if len(p) == 4: type_struct = type_format['uint32'] elif len(p) == 2: type_struct = type_format['uint16'] elif len(p) == 1: type_struct = type_format['uint8'] else: return data for i in type_struct.iter_unpack(data): val_int += [dtschema.sized_int(i[0], size=(type_struct.size * 8))] if 'matrix' in fmt or fmt in {'phandle', 'phandle-array', 'address'}: if dim: stride = get_stride(len(val_int), dim) #print(p.name, dim, stride, len(val_int)) return [val_int[i:i+stride] for i in range(0, len(val_int), stride)] else: return [val_int] elif 'array' not in fmt and len(val_int) == 1: return val_int[0] return val_int def node_props(validator, fdt, nodename, offset): props_dict = {} poffset = fdt.first_property_offset(offset, QUIET_NOTFOUND) while poffset >= 0: p = fdt.get_property_by_offset(poffset) props_dict[p.name] = prop_value(validator, nodename, p) poffset = fdt.next_property_offset(poffset, QUIET_NOTFOUND) return props_dict phandles = {} phandle_loc = [] def process_fixups(validator, fdt, nodename, offset): if nodename != '__fixups__': return props = node_props(validator, fdt, nodename, offset) global phandle_loc phandle_loc += [s for l in props.values() for s in l] def process_local_fixups(fdt, nodename, path, offset): global phandle_loc if nodename: path += '/' + nodename poffset = fdt.first_property_offset(offset, QUIET_NOTFOUND) while poffset >= 0: p = fdt.get_property_by_offset(poffset) for i in type_format['uint32'].iter_unpack(bytes(p)): phandle_loc += [path + ':' + p.name + ':' + str(i[0])] poffset = fdt.next_property_offset(poffset, QUIET_NOTFOUND) offset = fdt.first_subnode(offset, QUIET_NOTFOUND) while offset >= 0: nodename = fdt.get_name(offset) process_local_fixups(fdt, nodename, path, offset) offset = fdt.next_subnode(offset, QUIET_NOTFOUND) def fdt_scan_node(validator, fdt, nodename, offset): if nodename == '__fixups__': process_fixups(validator, fdt, nodename, offset) return if nodename == '__local_fixups__': process_local_fixups(fdt, '', '', offset) return if nodename.startswith('__'): return node_dict = node_props(validator, fdt, nodename, offset) if 'phandle' in node_dict: #print('phandle', node_dict['phandle']) phandles[node_dict['phandle']] = node_dict offset = fdt.first_subnode(offset, QUIET_NOTFOUND) while offset >= 0: nodename = fdt.get_name(offset) node = fdt_scan_node(validator, fdt, nodename, offset) if node is not None: node_dict[nodename] = node offset = fdt.next_subnode(offset, QUIET_NOTFOUND) return node_dict phandle_args = { # phandle+args properties with fixed arg size or which don't match standard # 'foos' and '#foo-cells' pattern 'assigned-clocks': '#clock-cells', 'assigned-clock-parents': '#clock-cells', 'cooling-device': '#cooling-cells', 'interrupts-extended': '#interrupt-cells', 'interconnects': '#interconnect-cells', 'mboxes': '#mbox-cells', 'sound-dai': '#sound-dai-cells', 'msi-parent': '#msi-cells', 'msi-ranges': '#interrupt-cells', 'dma-masters': '#dma-cells', 'gpio-ranges': 3, 'memory-region': None, } def _get_cells_size(node, cellname): if isinstance(cellname, int): return cellname elif cellname in node: return node[cellname] else: return 0 def _check_is_phandle(prop_path, cell): path = prop_path + ':' + str(cell * 4) return path in phandle_loc def _get_phandle_arg_size(prop_path, idx, cells, cellname): if not cells: return 0 phandle = cells[0] if phandle == 0 or not cellname: return 1 if phandle == 0xffffffff: # Use fixups data if available (examples) # Mixing unresolved and resolved phandles doesn't work if _check_is_phandle(prop_path, idx): cell_count = 1 while (cell_count < len(cells)) and not _check_is_phandle(prop_path, idx + cell_count): cell_count += 1 return cell_count else: return 0 if phandle not in phandles: return 0 node = phandles[phandle] return _get_cells_size(node, cellname) + 1 def fixup_phandles(validator, dt, path=''): for k, v in dt.items(): if isinstance(v, dict): fixup_phandles(validator, v, path=path + '/' + k) continue elif not {'phandle-array'} & set(validator.property_get_type(k)): continue elif k != 'dma-masters' and validator.property_has_fixed_dimensions(k): continue elif not isinstance(v, list) or (len(v) > 1 or not isinstance(v[0], list)): # Not a matrix or already split, nothing to do continue elif k in phandle_args: cellname = phandle_args[k] elif k.endswith('s') and 'gpio' not in k: cellname = '#' + k[:-1] + '-cells' #print(k, v) i = _get_phandle_arg_size(path + ':' + k, 0, v[0], cellname) if i == 0: continue else: continue # HACK around a type collision. Check if the phandle value points # to a DMA provider node or not. If not, then it's a uint32, not a # phandle. phandle = v[0][0] if k == 'dma-masters' and (phandle >= 1 and phandle <= 4) and \ (phandle not in phandles or cellname not in phandles[phandle]): dt[k] = phandle continue i = 0 dt[k] = [] val = v[0] #print(k, v) while i < len(val): #print(k, v, file=sys.stderr) cells = _get_phandle_arg_size(path + ':' + k, i, val[i:], cellname) if cells == 0: #print(k, v) break # Special case for msi-ranges which has an additional span cell if k == 'msi-ranges': cells += 1 # Special case for interconnects which is pairs of phandles+args if k == 'interconnects': cells += _get_phandle_arg_size(path + ':' + k, i + cells, val[i + cells:], cellname) dt[k] += [val[i:i + cells]] #print(k, dt[k], file=sys.stderr) i += cells def fixup_gpios(dt): if 'gpio-hog' in dt: return for k, v in dt.items(): if isinstance(v, dict): fixup_gpios(v) elif (k.endswith('-gpios') or k.endswith('-gpio') or k in {'gpio', 'gpios'}) and \ not k.endswith(',nr-gpios') and \ isinstance(v, list): i = 0 dt[k] = [] val = v[0] while i < len(val): phandle = val[i] if phandle == 0: cells = 0 elif phandle == 0xffffffff: #print(val, file=sys.stderr) try: cells = val.index(0xffffffff, i + 1, -1) except: cells = len(val) #print(cells, file=sys.stderr) cells -= (i + 1) else: #print(k, v, file=sys.stderr) node = phandles[phandle] cells = _get_cells_size(node, '#gpio-cells') dt[k] += [val[i:i + cells + 1]] i += cells + 1 def fixup_interrupts(dt, icells): if 'interrupt-parent' in dt and isinstance(dt['interrupt-parent'], list): phandle = dt['interrupt-parent'][0][0] if phandle == 0xffffffff: del dt['interrupt-parent'] else: icells = _get_cells_size(phandles[phandle], '#interrupt-cells') for k, v in dt.items(): if isinstance(v, dict): if '#interrupt-cells' in dt: icells = _get_cells_size(dt, '#interrupt-cells') fixup_interrupts(v, icells) elif k == 'interrupts' and not isinstance(v, bytes): i = 0 dt[k] = [] val = v[0] while i < len(val): dt[k] += [val[i:i + icells]] i += icells elif k == 'interrupt-map' and not isinstance(v, bytes): imap_icells = _get_cells_size(dt, '#interrupt-cells') ac = _get_cells_size(dt, '#address-cells') i = 0 dt[k] = [] val = v[0] phandle = val[ac + imap_icells] if phandle == 0xffffffff: # Assume uniform sizes (same interrupt provider) try: cells = val.index(0xffffffff, ac + imap_icells + 1) - (ac + imap_icells) except ValueError: cells = len(val) while i < len(val): dt[k] += [val[i:i + cells]] i += cells else: while i < len(val): p_icells = _get_cells_size(phandles[phandle], '#interrupt-cells') if '#address-cells' in phandles[phandle]: p_ac = _get_cells_size(phandles[phandle], '#address-cells') else: p_ac = 0 cells = ac + imap_icells + 1 + p_ac + p_icells dt[k] += [val[i:i + cells]] i += cells def fixup_addresses(validator, dt, ac, sc): for k, v in dt.items(): if isinstance(v, dict): if '#address-cells' in dt: ac = _get_cells_size(dt,'#address-cells') if '#size-cells' in dt: sc = _get_cells_size(dt, '#size-cells') fixup_addresses(validator, v, ac, sc) elif 'address' in validator.property_get_type(k): i = 0 dt[k] = [] val = v[0] while i < len(val): dt[k] += [val[i:i + ac + sc]] i += ac + sc elif k in {'ranges', 'dma-ranges'} and not isinstance(v, bool): child_cells = _get_cells_size(dt, '#address-cells') child_cells += _get_cells_size(dt, '#size-cells') i = 0 dt[k] = [] val = v[0] while i < len(val): dt[k] += [val[i:i + ac + child_cells]] i += ac + child_cells def fdt_unflatten(validator, dtb): fdt = libfdt.Fdt(dtb) offset = fdt.first_subnode(-1, QUIET_NOTFOUND) dt = fdt_scan_node(validator, fdt, '/', offset) #print(phandle_loc) fixup_gpios(dt) fixup_interrupts(dt, 1) fixup_addresses(validator, dt, 2, 1) fixup_phandles(validator, dt) # pprint.pprint(dt, compact=True) return dt dt-schema-2025.08/dtschema/dtb2py.py000077500000000000000000000024321504414563000171130ustar00rootroot00000000000000#!/usr/bin/python3 # SPDX-License-Identifier: BSD-2-Clause # Copyright 2022 Arm Ltd. import argparse import os import sys import pprint import dtschema strict = False def main(): ap = argparse.ArgumentParser() ap.add_argument("dtbfile", type=str, help="Schema directories and/or files") ap.add_argument('-s', '--schema', help="path to additional additional schema files") ap.add_argument('-V', '--version', help="Print version number", action="version", version=dtschema.__version__) args = ap.parse_args() if not os.path.isfile(args.dtbfile): exit(1) if args.schema: schemas = [args.schema] else: schemas = [] with open(args.dtbfile, 'rb') as f: dt = dtschema.DTValidator(schemas).decode_dtb(f.read()) try: pprint.pprint(dt, compact=True) # flush output here to force SIGPIPE to be triggered # while inside this try block. sys.stdout.flush() except BrokenPipeError: # Python flushes standard streams on exit; redirect remaining output # to devnull to avoid another BrokenPipeError at shutdown devnull = os.open(os.devnull, os.O_WRONLY) os.dup2(devnull, sys.stdout.fileno()) sys.exit(1) # Python exits with error code 1 on EPIPE dt-schema-2025.08/dtschema/dtb_validate.py000077500000000000000000000142411504414563000203320ustar00rootroot00000000000000#!/usr/bin/env python3 # SPDX-License-Identifier: BSD-2-Clause # Copyright 2018 Linaro Ltd. # Copyright 2018 Arm Ltd. import sys import os import argparse import glob import dtschema verbose = False show_unmatched = False match_schema_file = None compatible_match = False class schema_group(): def __init__(self, schema_file=""): if schema_file != "" and not os.path.exists(schema_file): exit(-1) self.validator = dtschema.DTValidator([schema_file]) def check_node(self, tree, node, disabled, nodename, fullname, filename): # Hack to save some time validating examples if 'example-0' in node or 'example-' in nodename: return node['$nodename'] = [nodename] try: for error in self.validator.iter_errors(node, filter=match_schema_file, compatible_match=compatible_match): # Disabled nodes might not have all the required # properties filled in, such as a regulator or a # GPIO meant to be filled at the DTS level on # boards using that particular node. Thus, if the # node is marked as disabled, let's just ignore # any error message reporting a missing property. if disabled or (isinstance(error.instance, dict) and 'status' in error.instance and 'disabled' in error.instance['status']): if {'required', 'unevaluatedProperties'} & set(error.schema_path): continue elif error.context: found = False for e in error.context: if {'required', 'unevaluatedProperties'} & set(e.schema_path): found = True break if found: continue if error.schema_file == 'generated-compatibles': if not show_unmatched: continue print(f"{filename}: {fullname}: failed to match any schema with compatible: {node['compatible']}", file=sys.stderr) continue if 'compatible' in node: compat = node['compatible'][0] else: compat = None print(dtschema.format_error(filename, error, nodename=nodename, compatible=compat, verbose=verbose), file=sys.stderr) except RecursionError as e: print(os.path.basename(sys.argv[0]) + ": recursion error: Check for prior errors in a referenced schema", file=sys.stderr) def check_subtree(self, tree, subtree, disabled, nodename, fullname, filename): if nodename.startswith('__'): return try: disabled = ('disabled' in subtree['status']) except: pass self.check_node(tree, subtree, disabled, nodename, fullname, filename) if fullname != "/": fullname += "/" for name, value in subtree.items(): if isinstance(value, dict): self.check_subtree(tree, value, disabled, name, fullname + name, filename) def check_dtb(self, filename): """Check the given DT against all schemas""" with open(filename, 'rb') as f: dt = self.validator.decode_dtb(f.read()) for subtree in dt: self.check_subtree(dt, subtree, False, "/", "/", filename) def main(): global verbose global show_unmatched global match_schema_file global compatible_match ap = argparse.ArgumentParser(fromfile_prefix_chars='@', epilog='Arguments can also be passed in a file prefixed with a "@" character.') ap.add_argument("dtbs", nargs='*', help="Filename or directory of devicetree DTB input file(s)") ap.add_argument('-s', '--schema', help="preparsed schema file or path to schema files") ap.add_argument('-p', '--preparse', help="preparsed schema file (deprecated, use '-s')") ap.add_argument('-l', '--limit', help="limit validation to schemas with $id matching LIMIT substring. " \ "Multiple substrings separated by ':' can be listed (e.g. foo:bar:baz).") ap.add_argument('-c', '--compatible-match', action="store_true", help="limit validation to schema matching nodes' most specific compatible string") ap.add_argument('-m', '--show-unmatched', help="Print out node 'compatible' strings which don't match any schema.", action="store_true") ap.add_argument('-n', '--line-number', help="Obsolete", action="store_true") ap.add_argument('-v', '--verbose', help="verbose mode", action="store_true") ap.add_argument('-u', '--url-path', help="Additional search path for references (deprecated)") ap.add_argument('-V', '--version', help="Print version number", action="version", version=dtschema.__version__) args = ap.parse_args() verbose = args.verbose show_unmatched = args.show_unmatched if args.limit: match_schema_file = args.limit.split(':') compatible_match = args.compatible_match # Maintain prior behaviour which accepted file paths by stripping the file path if args.url_path and args.limit: for i,match in enumerate(match_schema_file): for d in args.url_path.split(os.path.sep): if d and match.startswith(d): match = match[(len(d) + 1):] match_schema_file[i] = match if args.preparse: sg = schema_group(args.preparse) elif args.schema: sg = schema_group(args.schema) else: sg = schema_group() for d in args.dtbs: if not os.path.isdir(d): continue for filename in glob.iglob(d + "/**/*.dtb", recursive=True): if verbose: print("Check: " + filename) sg.check_dtb(filename) for filename in args.dtbs: if not os.path.isfile(filename): continue if verbose: print("Check: " + filename) sg.check_dtb(filename) dt-schema-2025.08/dtschema/extract_compatibles.py000077500000000000000000000022601504414563000217420ustar00rootroot00000000000000#!/usr/bin/env python3 # SPDX-License-Identifier: BSD-2-Clause # Copyright 2018 Linaro Ltd. # Copyright 2018 Arm Ltd. import os import argparse import ruamel.yaml yaml = ruamel.yaml.YAML() def item_generator(json_input, lookup_key): if isinstance(json_input, dict): for k, v in json_input.items(): if k == lookup_key: yield v else: for child_val in item_generator(v, lookup_key): yield child_val elif isinstance(json_input, list): for item in json_input: for item_val in item_generator(item, lookup_key): yield item_val def main(): ap = argparse.ArgumentParser() ap.add_argument("yamlfile", type=str, help="Filename of YAML encoded schema input file") args = ap.parse_args() schema_path = os.getcwd() testtree = yaml.load(open(args.yamlfile, encoding='utf-8').read()) compatible_list = [] for l in item_generator(testtree['properties']['compatible'], 'enum'): for _l in l: if _l not in compatible_list: compatible_list.append(_l) for c in compatible_list: print(c) dt-schema-2025.08/dtschema/extract_example.py000077500000000000000000000050651504414563000211010ustar00rootroot00000000000000#!/usr/bin/env python3 # SPDX-License-Identifier: BSD-2-Clause # Copyright 2018 Linaro Ltd. # Copyright 2019-2022 Arm Ltd. import re import sys import argparse import signal import ruamel.yaml def sigint_handler(signum, frame): sys.exit(-2) signal.signal(signal.SIGINT, sigint_handler) interrupt_template = """ interrupt-parent = <&fake_intc{index}>; fake_intc{index}: fake-interrupt-controller {{ interrupt-controller; #interrupt-cells = < {int_cells} >; }}; """ example_template = """ example-{example_num} {{ #address-cells = <1>; #size-cells = <1>; {interrupt} {example} }}; }}; """ example_header = """ /dts-v1/; /plugin/; // silence any missing phandle references """ example_start = """ /{ compatible = "foo"; model = "foo"; #address-cells = <1>; #size-cells = <1>; """ yaml = ruamel.yaml.YAML(typ='safe') def main(): ex = '// empty' ap = argparse.ArgumentParser() ap.add_argument("yamlfile", type=str, help="Filename of YAML encoded schema input file") args = ap.parse_args() try: binding = yaml.load(open(args.yamlfile, encoding='utf-8').read()) if not isinstance(binding, dict): exit(0) except ruamel.yaml.YAMLError as exc: print(args.yamlfile + ":" + str(exc.problem_mark.line + 1) + ":" + str(exc.problem_mark.column + 1) + ":", exc.problem, file=sys.stderr) exit(1) example_dts = example_header if 'examples' in binding.keys(): for idx, ex in enumerate(binding['examples']): # Check if example contains a root node "/{" root_node = re.search(r'/\s*{', ex) if not root_node: try: int_val = re.search(r'\sinterrupts\s*=\s*<([0-9a-zA-Z |()_]+)>', ex).group(1) int_val = re.sub(r'\(.+|\)', r'0', int_val) int_cells = len(int_val.strip().split()) except: int_cells = 0 example_dts += example_start ex = ' '.join(ex.splitlines(True)) if int_cells > 0: int_props = interrupt_template.format(int_cells=int_cells, index=idx) else: int_props = "" example_dts += example_template.format(example=ex, example_num=idx, interrupt=int_props) else: example_dts += ex else: example_dts += example_start example_dts += "\n};" print(example_dts) dt-schema-2025.08/dtschema/extract_props.py000077500000000000000000000033761504414563000206140ustar00rootroot00000000000000#!/usr/bin/python3 # SPDX-License-Identifier: BSD-2-Clause # Copyright 2022 Arm Ltd. import argparse import os import sys import pprint import dtschema strict = False def main(): ap = argparse.ArgumentParser() ap.add_argument("schema_files", type=str, nargs='*', help="preparsed schema file or list of additional schema files/directories") ap.add_argument('-d', '--duplicates', help="Only output properties with more than one type", action="store_true") ap.add_argument('-v', '--verbose', help="Additional search path for references", action="store_true") ap.add_argument('-V', '--version', help="Print version number", action="version", version=dtschema.__version__) args = ap.parse_args() dtval = dtschema.DTValidator(args.schema_files) props = dtval.property_get_all() if args.duplicates: tmp_props = {} for k, v in props.items(): if len(v) > 1: tmp_props[k] = v props = tmp_props if args.verbose: prop_types = props else: prop_types = {} for k, v in props.items(): prop_types[k] = [] for l in v: if 'type' in l: prop_types[k] += [l['type']] try: pprint.pprint(prop_types, compact=True) # flush output here to force SIGPIPE to be triggered # while inside this try block. sys.stdout.flush() except BrokenPipeError: # Python flushes standard streams on exit; redirect remaining output # to devnull to avoid another BrokenPipeError at shutdown devnull = os.open(os.devnull, os.O_WRONLY) os.dup2(devnull, sys.stdout.fileno()) sys.exit(1) # Python exits with error code 1 on EPIPE dt-schema-2025.08/dtschema/fixups.py000066400000000000000000000325341504414563000172300ustar00rootroot00000000000000# SPDX-License-Identifier: BSD-2-Clause # Copyright 2018 Linaro Ltd. # Copyright 2018-2023 Arm Ltd. # Python library for Devicetree schema validation import re import copy import dtschema from dtschema.lib import _get_array_range from dtschema.lib import _is_int_schema from dtschema.lib import _is_string_schema def _extract_single_schemas(subschema): scalar_keywords = ('const', 'enum', 'pattern', 'minimum', 'maximum', 'multipleOf') return {k: subschema.pop(k) for k in scalar_keywords if k in subschema} def _fixup_string_to_array(subschema): # nothing to do if we don't have a set of string schema if not _is_string_schema(subschema): return subschema['items'] = [_extract_single_schemas(subschema)] def _fixup_reg_schema(subschema, path=[]): # nothing to do if we don't have a set of string schema if 'reg' not in path: return if 'items' in subschema: if isinstance(subschema['items'], list): item_schema = subschema['items'][0] else: item_schema = subschema['items'] if not _is_int_schema(item_schema): return elif _is_int_schema(subschema): item_schema = subschema else: return subschema['items'] = [{'items': [_extract_single_schemas(item_schema)]}] def _is_matrix_schema(subschema): if 'items' not in subschema: return False if isinstance(subschema['items'], list): for l in subschema['items']: if l.keys() & {'items', 'maxItems', 'minItems'}: return True elif subschema['items'].keys() & {'items', 'maxItems', 'minItems'}: return True return False def _fixup_remove_empty_items(subschema): if 'items' not in subschema: return elif isinstance(subschema['items'], dict): _fixup_remove_empty_items(subschema['items']) return for item in subschema['items']: if not isinstance(item, dict): continue item.pop('description', None) _fixup_remove_empty_items(item) if item != {}: break else: subschema.setdefault('type', 'array') subschema.setdefault('maxItems', len(subschema['items'])) subschema.setdefault('minItems', len(subschema['items'])) del subschema['items'] # Keep in sync with property-units.yaml unit_types_array_re = re.compile('-(kBps|bits|percent|bp|db|mhz|sec|ms|us|ns|ps|mm|nanoamp|(micro-)?ohms|micro(amp|watt)(-hours)?|milliwatt|(femto|pico)farads|(milli)?celsius|kelvin|k?pascal)$') unit_types_matrix_re = re.compile('-(hz|microvolt)$') def _fixup_unit_suffix_props(subschema, path=[]): path.reverse() for idx, p in enumerate(path): if p in {'properties', '$defs'}: propname = path[idx - 1] break else: return if unit_types_array_re.search(propname) and _is_int_schema(subschema): subschema['items'] = [_extract_single_schemas(subschema)] elif unit_types_matrix_re.search(propname): if _is_matrix_schema(subschema): return if {'items', 'minItems', 'maxItems'} & subschema.keys(): subschema['items'] = [copy.deepcopy(subschema)] subschema.pop('minItems', None) subschema.pop('maxItems', None) #print(subschema, file=sys.stderr) elif _is_int_schema(subschema): subschema['items'] = [{'items': [_extract_single_schemas(subschema)]}] def _fixup_items_size(schema, path=[]): # Make items list fixed size-spec if isinstance(schema, list): for l in schema: _fixup_items_size(l, path=path) elif isinstance(schema, dict): schema.pop('description', None) if 'items' in schema: schema['type'] = 'array' if isinstance(schema['items'], list): c = len(schema['items']) if 'minItems' not in schema: schema['minItems'] = c if 'maxItems' not in schema: schema['maxItems'] = c _fixup_items_size(schema['items'], path=path + ['items']) elif not {'then', 'else'} & set(path): if 'maxItems' in schema and 'minItems' not in schema: schema['minItems'] = schema['maxItems'] elif 'minItems' in schema and 'maxItems' not in schema: schema['maxItems'] = schema['minItems'] def fixup_schema_to_201909(schema): if not isinstance(schema, dict): return # dependencies is now split into dependentRequired and dependentSchema try: val = schema.pop('dependencies') for k, v in val.items(): if isinstance(v, list): schema.setdefault('dependentRequired', {}) schema['dependentRequired'][k] = v else: schema.setdefault('dependentSchemas', {}) schema['dependentSchemas'][k] = v except: pass def fixup_schema_to_202012(schema): if not isinstance(schema, dict): return fixup_schema_to_201909(schema) try: if isinstance(schema['items'], list): schema['prefixItems'] = schema.pop('items') for i in schema['prefixItems']: fixup_schema_to_202012(i) if isinstance(schema['items'], dict): fixup_schema_to_202012(schema['items']) except: pass try: val = schema.pop('additionalItems') schema['unevaluatedItems'] = val except: pass def fixup_vals(schema, path=[]): # Now we should be a the schema level to do actual fixups #print(schema) schema.pop('description', None) _fixup_reg_schema(schema, path=path) _fixup_remove_empty_items(schema) _fixup_unit_suffix_props(schema, path=path) _fixup_string_to_array(schema) _fixup_items_size(schema, path=path) fixup_schema_to_201909(schema) def _fixup_oneOf_to_enum(schema, path=[]): # Convert oneOf/anyOf lists with just 'const' entries into an enum. # This pattern is used to add descriptions on each entry which is not # possible with 'enum', but the error reporting is much worse with # oneOf/anyOf schemas. if 'anyOf' in schema: sch_list = schema['anyOf'] elif 'oneOf' in schema: sch_list = schema['oneOf'] elif 'items' in schema and isinstance(schema['items'], dict): # Sometimes 'items' appears first which isn't really handled by the # fixups, but we can handle it here. _fixup_oneOf_to_enum(schema['items'], path=path + ['items']) return else: return const_list = [] for l in sch_list: if 'const' not in l or set(l) > {'const', 'description'}: return const_list += [l['const']] schema.pop('anyOf', None) schema.pop('oneOf', None) schema['enum'] = const_list def walk_properties(schema, path=[]): if not isinstance(schema, dict): return _fixup_oneOf_to_enum(schema, path=path) # Recurse until we don't hit a conditional # Note we expect to encounter conditionals first. # For example, a conditional below 'items' is not supported for cond in ['allOf', 'oneOf', 'anyOf']: if cond in schema.keys(): for l in schema[cond]: walk_properties(l, path=path + [cond]) if 'then' in schema.keys(): walk_properties(schema['then'], path=path + ['then']) fixup_vals(schema, path=path) def fixup_interrupts(schema, path): # Supporting 'interrupts' implies 'interrupts-extended' is also supported. if 'properties' in schema: # Any node with 'interrupts' can have 'interrupt-parent' if schema['properties'].keys() & {'interrupts', 'interrupt-controller'} and \ 'interrupt-parent' not in schema['properties']: schema['properties']['interrupt-parent'] = True if 'interrupts' not in schema['properties'] or 'interrupts-extended' in schema['properties']: return schema['properties']['interrupts-extended'] = copy.deepcopy(schema['properties']['interrupts']) if 'required' in schema and 'interrupts' in schema['required'] and \ (len(path) == 0 or path[-1] != 'oneOf'): # Currently no better way to express either 'interrupts' or 'interrupts-extended' # is required. If this fails validation, the error reporting is the whole # schema file fails validation reqlist = [{'required': ['interrupts']}, {'required': ['interrupts-extended']}] if 'oneOf' in schema: if 'allOf' not in schema: schema['allOf'] = [] schema['allOf'].append({'oneOf': reqlist}) else: schema['oneOf'] = reqlist schema['required'].remove('interrupts') if len(schema['required']) == 0: schema.pop('required') known_variable_matrix_props = { 'fsl,pins', 'qcom,board-id' } def fixup_sub_schema(schema, path=[]): if not isinstance(schema, dict): return schema.pop('description', None) fixup_interrupts(schema, path) fixup_node_props(schema) # 'additionalProperties: true' doesn't work with 'unevaluatedProperties', so # remove it. It's in the schemas for common (incomplete) schemas. if 'additionalProperties' in schema and schema['additionalProperties'] == True: schema.pop('additionalProperties', None) for k, v in schema.items(): if k in ['select', 'if', 'then', 'else', 'not', 'additionalProperties']: fixup_sub_schema(v, path=path + [k]) if k in ['allOf', 'anyOf', 'oneOf']: for subschema in v: fixup_sub_schema(subschema, path=path + [k]) if k not in ['dependentRequired', 'dependentSchemas', 'dependencies', 'properties', 'patternProperties', '$defs']: continue for prop in v: if prop in known_variable_matrix_props and isinstance(v[prop], dict): ref = v[prop].pop('$ref', None) schema[k][prop] = {} if ref: schema[k][prop]['$ref'] = ref continue walk_properties(v[prop], path=path + [k, prop]) # Recurse to check for {properties,patternProperties} in each prop fixup_sub_schema(v[prop], path=path + [k, prop]) fixup_schema_to_201909(schema) def fixup_node_props(schema): if not {'unevaluatedProperties', 'additionalProperties'} & schema.keys(): return keys = [] if 'properties' in schema: keys.extend(schema['properties'].keys()) if 'patternProperties' in schema: keys.extend(schema['patternProperties']) if "clocks" in keys and "assigned-clocks" not in keys: schema['properties']['assigned-clocks'] = True schema['properties']['assigned-clock-rates-u64'] = True schema['properties']['assigned-clock-rates'] = True schema['properties']['assigned-clock-parents'] = True schema['properties']['assigned-clock-sscs'] = True # 'dma-ranges' allowed when 'ranges' is present if 'ranges' in keys: schema['properties'].setdefault('dma-ranges', True) # If no restrictions on undefined properties, then no need to add any implicit properties if ('additionalProperties' in schema and schema['additionalProperties'] is True) or \ ('unevaluatedProperties' in schema and schema['unevaluatedProperties'] is True): return schema.setdefault('properties', dict()) schema['properties'].setdefault('phandle', True) schema['properties'].setdefault('status', True) schema['properties'].setdefault('secure-status', True) schema['properties'].setdefault('$nodename', True) schema['properties'].setdefault('bootph-pre-sram', True) schema['properties'].setdefault('bootph-verify', True) schema['properties'].setdefault('bootph-pre-ram', True) schema['properties'].setdefault('bootph-some-ram', True) schema['properties'].setdefault('bootph-all', True) for key in keys: if re.match(r'^pinctrl-[0-9]', key): break else: schema['properties'].setdefault('pinctrl-names', True) schema.setdefault('patternProperties', dict()) schema['patternProperties']['^pinctrl-[0-9]+$'] = True # Convert to standard types from ruamel's CommentedMap/Seq def convert_to_dict(schema): if isinstance(schema, dict): result = {} for k, v in schema.items(): result[k] = convert_to_dict(v) elif isinstance(schema, list): result = [] for item in schema: result.append(convert_to_dict(item)) else: result = schema return result def add_select_schema(schema): '''Get a schema to be used in select tests. If the provided schema has a 'select' property, then use that as the select schema. If it has a $nodename property, then create a select schema from that. ''' if "select" in schema: return if 'properties' not in schema or 'compatible' in schema['properties']: return if '$nodename' in schema['properties'] and schema['properties']['$nodename'] is not True: schema['select'] = { 'required': ['$nodename'], 'properties': {'$nodename': convert_to_dict(schema['properties']['$nodename'])}} return def fixup_schema(schema): # Remove parts not necessary for validation schema.pop('examples', None) schema.pop('maintainers', None) schema.pop('historical', None) add_select_schema(schema) fixup_sub_schema(schema) dt-schema-2025.08/dtschema/lib.py000066400000000000000000000111511504414563000164500ustar00rootroot00000000000000# SPDX-License-Identifier: BSD-2-Clause # Copyright 2018 Linaro Ltd. # Copyright 2018-2023 Arm Ltd. # Python library for Devicetree schema validation import os import re from jsonschema.exceptions import best_match # We use a lot of regex's in schema and exceeding the cache size has noticeable # peformance impact. re._MAXCACHE = 2048 class sized_int(int): def __new__(cls, value, *args, **kwargs): return int.__new__(cls, value) def __init__(self, value, size=32): self.size = size def _value_is_type(subschema, key, type): if key not in subschema: return False if isinstance(subschema[key], list): val = subschema[key][0] else: val = subschema[key] return isinstance(val, type) def _is_int_schema(subschema): if not isinstance(subschema, dict): return False for match in ['const', 'enum', 'minimum', 'maximum']: if _value_is_type(subschema, match, int): return True return False def _is_string_schema(subschema): if not isinstance(subschema, dict): return False for match in ['const', 'enum', 'pattern']: if _value_is_type(subschema, match, str): return True return False def extract_node_compatibles(schema): if not isinstance(schema, dict): return set() compatible_list = set() for l in item_generator(schema, 'enum'): if isinstance(l[0], str): compatible_list.update(l) for l in item_generator(schema, 'const'): compatible_list.update([str(l)]) for l in item_generator(schema, 'pattern'): compatible_list.update([l]) return compatible_list def extract_compatibles(schema): if not isinstance(schema, dict): return set() compatible_list = set() for sch in item_generator(schema, 'compatible'): compatible_list.update(extract_node_compatibles(sch)) return compatible_list def item_generator(json_input, lookup_key): if isinstance(json_input, dict): for k, v in json_input.items(): if k == lookup_key: yield v else: for child_val in item_generator(v, lookup_key): yield child_val elif isinstance(json_input, list): for item in json_input: for item_val in item_generator(item, lookup_key): yield item_val def _get_array_range(subschema): if isinstance(subschema, list): if len(subschema) != 1: return (0, 0) subschema = subschema[0] if 'items' in subschema and isinstance(subschema['items'], list): max = len(subschema['items']) min = subschema.get('minItems', max) else: min = subschema.get('minItems', 1) max = subschema.get('maxItems', subschema.get('minItems', 0)) return (min, max) def format_error(filename, error, prefix="", nodename=None, compatible=None, verbose=False): src = prefix + os.path.abspath(filename) + ':' if hasattr(error, 'linecol') and error.linecol[0] >= 0: src = src + '%i:%i: ' % (error.linecol[0]+1, error.linecol[1]+1) else: src += ' ' if nodename is not None: src += nodename if compatible is not None: src += f" ({compatible})" src += ': ' if error.absolute_path: for path in error.absolute_path: src += str(path) + ":" src += ' ' #print(error.__dict__) if verbose: msg = str(error) elif not error.schema_path: msg = error.message elif error.context: if len(error.context) == 1: msg = best_match(error.context).message else: # An error on a conditional will have context with sub-errors msg = "'" + error.schema_path[-1] + "' conditional failed, one must be fixed:" for suberror in sorted(error.context, key=lambda e: e.path): if suberror.context: msg += '\n' + format_error(filename, suberror, prefix=prefix+"\t", nodename=nodename, compatible=compatible, verbose=verbose) elif suberror.message not in msg: msg += '\n' + prefix + '\t' + suberror.message if hasattr(suberror, 'note') and suberror.note and suberror.note != error.note: msg += '\n\t\t' + prefix + 'hint: ' + suberror.note else: msg = error.message if hasattr(error, 'note') and error.note: msg += '\n\t' + prefix + 'hint: ' + error.note if hasattr(error, 'schema_file') and error.schema_file: msg += '\n\t' + prefix + 'from schema $id: ' + error.schema_file return src + msg dt-schema-2025.08/dtschema/meta-schemas/000077500000000000000000000000001504414563000177005ustar00rootroot00000000000000dt-schema-2025.08/dtschema/meta-schemas/base.yaml000066400000000000000000000036631504414563000215060ustar00rootroot00000000000000# SPDX-License-Identifier: BSD-2-Clause # Copyright 2018 Linaro Ltd. # Copyright 2018 Arm Ltd. %YAML 1.2 --- $id: http://devicetree.org/meta-schemas/base.yaml# $schema: https://json-schema.org/draft/2019-09/schema description: Metaschema for devicetree binding documentation allOf: - $ref: http://json-schema.org/draft-07/schema# - $ref: http://devicetree.org/meta-schemas/keywords.yaml# properties: # listing all properties here to narrow the scope of what is allowed in # devicetree schema files. This list can be relaxed in the future as we # become more comfortable with the validation vocabulary. # Also, being explicit about what properties are allowed helps to catch # misspelled or unsupported tests. $id: pattern: 'http://devicetree.org/schemas(/[^/ ]+)+\.yaml#' $schema: enum: - "http://devicetree.org/meta-schemas/core.yaml#" - "http://devicetree.org/meta-schemas/base.yaml#" title: maxLength: 100 description: Everything is a binding/schema, no need to say it. Describe what hardware the binding is for. not: pattern: '([Bb]inding| [Ss]chema)' examples: type: array items: type: string maintainers: type: array items: pattern: '@' type: string format: email select: description: '"select" must contain a valid json-schema' allOf: - $ref: http://json-schema.org/draft-07/schema# - oneOf: - type: object properties: properties: true required: true - type: boolean propertyNames: enum: [ $id, $schema, title, description, examples, required, allOf, anyOf, oneOf, definitions, $defs, additionalProperties, dependencies, dependentRequired, dependentSchemas, patternProperties, properties, not, if, then, else, unevaluatedProperties, deprecated, maintainers, select, $ref ] required: - $id - $schema - title - maintainers dt-schema-2025.08/dtschema/meta-schemas/boolean.yaml000066400000000000000000000005171504414563000222060ustar00rootroot00000000000000# SPDX-License-Identifier: BSD-2-Clause # Copyright 2018 Linaro Ltd. # Copyright 2018 Arm Ltd. %YAML 1.2 --- $id: http://devicetree.org/meta-schemas/boolean.yaml# $schema: https://json-schema.org/draft/2019-09/schema properties: type: const: boolean description: {} default: {} deprecated: {} additionalProperties: false dt-schema-2025.08/dtschema/meta-schemas/cell.yaml000066400000000000000000000043201504414563000215020ustar00rootroot00000000000000# SPDX-License-Identifier: BSD-2-Clause # Copyright 2018 Linaro Ltd. # Copyright 2018 Arm Ltd. %YAML 1.2 --- $id: http://devicetree.org/meta-schemas/cell.yaml# $schema: https://json-schema.org/draft/2019-09/schema array: description: cell array properties must define how many entries and what the entries are when there is more than one entry. anyOf: - description: 'Only "maxItems" is required for a single entry if there are no constraints defined for the values.' properties: maxItems: const: 1 required: [maxItems] propertyNames: enum: [maxItems, description, deprecated] - description: Arrays must be described with a combination of minItems/maxItems/items properties: minItems: minimum: 1 maxItems: minimum: 2 oneOf: type: array items: $ref: '#/array' anyOf: type: array items: $ref: '#/array' items: description: '"items" can be a list defining each entry or a schema applying to all items. A list has an implicit size. A schema requires minItems/maxItems to define the size.' if: type: object then: $ref: '#/array' else: type: array if: items: required: [ items ] then: maxItems: 1 # for more than 1, outer 'items' should be a schema items: $ref: '#/array' else: items: $ref: '#/single' additionalItems: type: boolean const: true description: true deprecated: true additionalProperties: false - $ref: '#/single' single: description: A singular entry should be described with scalar constraints properties: description: true const: type: integer enum: items: type: integer minimum: {} maximum: {} default: type: integer oneOf: items: $ref: '#/single' propertyNames: enum: [ description, deprecated, const, enum, minimum, maximum, multipleOf, default, $ref, oneOf ] dt-schema-2025.08/dtschema/meta-schemas/clocks.yaml000066400000000000000000000021571504414563000220470ustar00rootroot00000000000000# SPDX-License-Identifier: BSD-2-Clause # Copyright 2018 Linaro Ltd. # Copyright 2018 Arm Ltd. %YAML 1.2 --- $id: http://devicetree.org/meta-schemas/clocks.yaml# $schema: https://json-schema.org/draft/2019-09/schema properties: clocks: if: type: object required: [type] then: $ref: nodes.yaml else: $ref: cell.yaml#/array clock-ranges: $ref: boolean.yaml clock-indices: $ref: cell.yaml#/array assigned-clocks: $ref: cell.yaml#/array assigned-clock-parents: $ref: cell.yaml#/array assigned-clock-rates: $ref: cell.yaml#/array assigned-clock-rates-u64: $ref: cell.yaml#/array assigned-clock-sscs: $ref: cell.yaml#/array clock-frequency: $ref: cell.yaml#/single bus-frequency: $ref: cell.yaml#/single dependentRequired: clock-output-names: ['#clock-cells'] clock-indices: ['#clock-cells'] clock-names: [clocks] clock-ranges: [clocks] assigned-clocks: [clocks] assigned-clock-parents: [assigned-clocks] assigned-clock-rates: [assigned-clocks] assigned-clock-rates-u64: [assigned-clocks] assigned-clock-sscs: [assigned-clocks] dt-schema-2025.08/dtschema/meta-schemas/core.yaml000066400000000000000000000101441504414563000215140ustar00rootroot00000000000000# SPDX-License-Identifier: BSD-2-Clause # Copyright 2018 Linaro Ltd. # Copyright 2018-2019 Arm Ltd. %YAML 1.2 --- $id: http://devicetree.org/meta-schemas/core.yaml# $schema: https://json-schema.org/draft/2019-09/schema description: Metaschema for devicetree binding documentation allOf: - $ref: http://devicetree.org/meta-schemas/base.yaml# - description: Either unevaluatedProperties or additionalProperties must be present oneOf: - required: [ unevaluatedProperties ] - required: [ additionalProperties ] definitions: unit-suffix-properties: $ref: cell.yaml#/array propertyNames: description: Standard unit suffix properties don't need a type $ref not: const: $ref all-properties: allOf: - $ref: "#/definitions/core-properties" - $ref: clocks.yaml# - $ref: dma.yaml# - $ref: gpios.yaml# - $ref: hwlock.yaml# - $ref: iio.yaml# - $ref: interrupts.yaml# - $ref: iommu.yaml# - $ref: mailbox.yaml# - $ref: nvmem.yaml# - $ref: phy.yaml# - $ref: power-domain.yaml# - $ref: pwm.yaml# - $ref: reset.yaml# - $ref: mailbox.yaml# - $ref: vendor-props.yaml# core-properties: properties: ranges: $ref: cell.yaml#/array reg: $ref: cell.yaml#/array compatible: $ref: string-array.yaml $nodename: $ref: string-array.yaml memory-region: $ref: cell.yaml#/array memory-region-names: $ref: string-array.yaml patternProperties: '.*-names$': $ref: string-array.yaml '^#.*-cells$': $ref: cell.yaml#/single '-supply$': propertyNames: enum: [ description, deprecated ] '-(bits|bps|kBps|percent|bp|db|mhz|hz|sec|ms|us|ns|ps|mm|nanoamp|microamp(-hours)?|micro-ohms|microwatt-hours|microvolt|(femto|pico)farads|(milli)?celsius|kelvin|k?pascal)$': $ref: '#/definitions/unit-suffix-properties' # Some special cases which don't match the normal size. '(? 0: self.validator().resolver.pop_scope() ref_depth -= 1 if isinstance(error.schema, dict) and 'description' in error.schema: error.note = error.schema['description'] def iter_errors(self): meta_schema = self.validator().resolver.resolve_from_url(self['$schema']) for error in self.validator().iter_errors(self): scherr = jsonschema.exceptions.SchemaError.create_from(error) self.annotate_error(scherr, meta_schema, scherr.schema_path) scherr.linecol = get_line_col(self, scherr.path) yield scherr def is_valid(self, strict=False): ''' Check if schema passes validation against json-schema.org schema ''' if strict: for error in self.iter_errors(): raise error else: # Using the draft7 metaschema because 2019-09 with $recursiveRef seems broken # Probably fixed with referencing library for error in self.DtValidator(jsonschema.Draft7Validator.META_SCHEMA).iter_errors(self): scherr = jsonschema.exceptions.SchemaError.create_from(error) raise scherr def fixup(self): processed_schema = copy.deepcopy(dict(self)) dtschema.fixups.fixup_schema(processed_schema) return processed_schema def _check_schema_refs(self, schema, parent=None, is_common=False, has_constraint=False): if not parent: is_common = not _schema_allows_no_undefined_props(schema) if isinstance(schema, dict): if parent in {'if', 'select', 'definitions', '$defs', 'then', 'else', 'dependencies', 'dependentSchemas'}: return if _is_node_schema(schema): has_constraint = _schema_allows_no_undefined_props(schema) ref_has_constraint = True if '$ref' in schema: ref = schema['$ref'] url, ref_sch = self.validator().resolver.resolve(ref) ref_has_constraint = _schema_allows_no_undefined_props(ref_sch) if not (is_common or ref_has_constraint or has_constraint or (schema.keys() & {'additionalProperties', 'unevaluatedProperties'})): print(f"{self.filename}: {parent}: Missing additionalProperties/unevaluatedProperties constraint\n", file=sys.stderr) for k, v in schema.items(): self._check_schema_refs(v, parent=k, is_common=is_common, has_constraint=has_constraint) elif isinstance(schema, (list, tuple)): for i in range(len(schema)): self._check_schema_refs(schema[i], parent=parent, is_common=is_common, has_constraint=has_constraint) def check_schema_refs(self): id = self['$id'].rstrip('#') base1 = re.search('schemas/(.+)$', id)[1] base2 = self.filename.replace(self.filename[:-len(base1)], '') if not base1 == base2: print(f"{self.filename}: $id: Cannot determine base path from $id, relative path/filename doesn't match actual path or filename\n", f"\t $id: {id}\n", f"\tfile: {self.filename}", file=sys.stderr) return scope = self.validator().ID_OF(self) if scope: self.validator().resolver.push_scope(scope) self.paths = [ (schema_base_url + 'schemas/', self.base_path), (schema_base_url + 'schemas/', schema_basedir + '/schemas/'), ] try: self._check_schema_refs(self) except jsonschema.RefResolutionError as exc: print(f"{self.filename}:\n\t{exc}", file=sys.stderr) dt-schema-2025.08/dtschema/schemas/000077500000000000000000000000001504414563000167545ustar00rootroot00000000000000dt-schema-2025.08/dtschema/schemas/access-controller/000077500000000000000000000000001504414563000223765ustar00rootroot00000000000000dt-schema-2025.08/dtschema/schemas/access-controller/access-controller-consumer.yaml000066400000000000000000000011171504414563000305350ustar00rootroot00000000000000# SPDX-License-Identifier: BSD-2-Clause # Copyright 2024 NXP %YAML 1.2 --- $id: http://devicetree.org/schemas/access-controller/access-controller-consumer.yaml# $schema: http://devicetree.org/meta-schemas/core.yaml# title: Access Controller Consumer Properties maintainers: - Peng Fan select: true properties: access-controllers: $ref: /schemas/types.yaml#/definitions/phandle-array description: This property is applied to the access controller consumer to describe the connection to an access controller provider. additionalProperties: true dt-schema-2025.08/dtschema/schemas/aliases.yaml000066400000000000000000000034141504414563000212630ustar00rootroot00000000000000# SPDX-License-Identifier: BSD-2-Clause # Copyright 2018 Linaro Ltd. # Copyright 2018 Arm Ltd. %YAML 1.2 --- $id: http://devicetree.org/schemas/aliases.yaml# $schema: http://devicetree.org/meta-schemas/core.yaml# title: /aliases Node description: | A devicetree may have an aliases node (``/aliases``) that defines one or more alias properties. The aliases node shall be at the root of the devicetree and have the node name ``/aliases``. Each property of the ``/aliases`` node defines an alias, which can be used as a shorthand name for a node in the tree. The property name is the alias name, and the property value contains the full path to a node encoded as a string. For example, the property ``serial0 = "/simple-bus@fe000000/serial@11c500";`` defines the alias ``serial0``. An alias name must be a lowercase text string of 1 to 31 characters from the following character set. .. tabularcolumns:: | c p{8cm} | .. table:: Valid characters for alias names ========= ================ Character Description ========= ================ 0-9 digit a-z lowercase letter \- dash ========= ================ A client program may use an alias property name to refer to a full device path as all or part of its string value. A client program, when considering a string as a device path, shall detect and use the alias. properties: $nodename: const: aliases patternProperties: "^[a-z][a-z0-9\\-]*$": $ref: types.yaml#/definitions/string additionalProperties: false examples: - | aliases { serial0 = "/simple-bus@fe000000/serial@11c500"; ethernet0 = "/simple-bus@fe000000/ethernet@31c000"; }; maintainers: - Devicetree Specification Mailing List dt-schema-2025.08/dtschema/schemas/bootph.yaml000066400000000000000000000062041504414563000211350ustar00rootroot00000000000000# SPDX-License-Identifier: BSD-2-Clause # Copyright 2022 Google LLC %YAML 1.2 --- $id: http://devicetree.org/schemas/bootph.yaml# $schema: http://devicetree.org/meta-schemas/core.yaml# title: Boot-phase-specific device nodes maintainers: - Simon Glass description: | Some programs run in memory-constrained environments yet want to make use of device tree. The full device tree is often quite large relative to the available memory of a boot phase, so cannot fit into every phase of the boot process. Even when memory is not a problem, some phases may wish to limit which device nodes are present, so as to reduce execution time. This binding supports adding tags to device tree nodes to allow them to be marked according to the phases where they should be included. Without any tags, nodes are included only in the final phase, where all memory is available. Any untagged nodes are dropped from previous phases and are ignored before the final phase is reached. The build process produces a separate executable for each phase. It can use fdtgrep to drop any nodes which are not needed for a particular build. For example, the pre-sram build will drop any nodes which are not marked with bootph-pre-sram or bootph-all tags. Note that phase builds may drop the tags, since they have served their purpose by that point. So when looking at phase-specific device tree files you may not see these tags. Multiple tags can be used in the same node. Tags in a child node are implied to be present in all parent nodes as well. This is important, since some missing properties (such as "ranges", or "compatible") can cause the child node to be ignored or incorrectly parsed. That said, at present, fdtgrep applies tags only to the node they are added to, not to any parents. This means U-Boot device tree files often add the same tag to parent nodes, rather than relying on tooling to do this. This is a limitation of fdtgrep and it will be addressed so that 'Linux DTs' do not need to do this. The available tags are described as properties below, in order of phase execution. select: true properties: bootph-pre-sram: type: boolean description: Enable this node when SRAM is not available. This phase must set up some SRAM or cache-as-RAM so it can obtain data/BSS space to use during execution. bootph-verify: type: boolean description: Enable this node in the verification step, which decides which of the available images should be run next. bootph-pre-ram: type: boolean description: Enable this node in the phase that sets up SDRAM. bootph-some-ram: type: boolean description: Enable this node in the phase that is run after SDRAM is working but before all of it is available. Some RAM is available but it is limited (e.g. it may be split into two pieces by the location of the running program) because the program code is not yet relocated out of the way. bootph-all: type: boolean description: Include this node in all phases (for U-Boot see enum u_boot_phase). additionalProperties: true dt-schema-2025.08/dtschema/schemas/bus/000077500000000000000000000000001504414563000175455ustar00rootroot00000000000000dt-schema-2025.08/dtschema/schemas/bus/qemu,platform.yaml000066400000000000000000000021221504414563000232160ustar00rootroot00000000000000# SPDX-License-Identifier: BSD-2-Clause # Copyright 2022 Arm Ltd. %YAML 1.2 --- $id: http://devicetree.org/schemas/bus/qemu,platform.yaml# $schema: http://devicetree.org/meta-schemas/core.yaml# title: QEMU Platform bus maintainers: - Rob Herring select: properties: compatible: contains: const: qemu,platform required: - compatible properties: compatible: items: - const: qemu,platform - const: simple-bus ranges: true dma-ranges: true "#address-cells": enum: [ 1, 2 ] "#size-cells": enum: [ 1, 2 ] nonposted-mmio: $ref: /schemas/types.yaml#/definitions/flag description: If present, specifies that direct children of this bus should use non-posted memory accesses (i.e. a non-posted mapping mode) for MMIO ranges. interrupt-parent: true patternProperties: # All other properties should be child nodes with unit-address and 'reg' "@(0|[1-9a-f][0-9a-f]*)$": type: object additionalProperties: false required: - compatible - "#address-cells" - "#size-cells" - ranges ... dt-schema-2025.08/dtschema/schemas/cache-controller.yaml000066400000000000000000000024571504414563000230740ustar00rootroot00000000000000# SPDX-License-Identifier: BSD-2-Clause # Copyright 2019 Linaro Ltd. # Copyright 2022 Arm Ltd. %YAML 1.2 --- $id: http://devicetree.org/schemas/cache-controller.yaml# $schema: http://devicetree.org/meta-schemas/base.yaml# title: Common Cache Properties maintainers: - Rob Herring properties: cache-level: $ref: /schemas/types.yaml#/definitions/uint32 minimum: 2 maximum: 32 cache-unified: $ref: /schemas/types.yaml#/definitions/flag next-level-cache: $ref: /schemas/types.yaml#/definitions/phandle patternProperties: "^(i-|d-|)cache-size$": $ref: /schemas/types.yaml#/definitions/uint32 "^(i-|d-|)cache-sets$": $ref: /schemas/types.yaml#/definitions/uint32 "^(i-|d-|)cache-block-size$": $ref: /schemas/types.yaml#/definitions/uint32 "^(i-|d-|)cache-line-size$": $ref: /schemas/types.yaml#/definitions/uint32 dependentRequired: cache-size: [ cache-unified ] cache-sets: [ cache-unified ] cache-block-size: [ cache-unified ] cache-line-size: [ cache-unified ] cache-level: [ compatible ] dependentSchemas: cache-unified: patternProperties: '^[id]-cache-': false if: not: properties: device_type: const: cpu required: - device_type then: required: - cache-level additionalProperties: true dt-schema-2025.08/dtschema/schemas/cache.yaml000066400000000000000000000020551504414563000207050ustar00rootroot00000000000000# SPDX-License-Identifier: BSD-2-Clause # Copyright 2022 Arm Ltd. %YAML 1.2 --- $id: http://devicetree.org/schemas/cache.yaml# $schema: http://devicetree.org/meta-schemas/base.yaml# title: Generic 'cache' Nodes description: Generic cache binding for caches nodes which only have common cache properties. A cache with a register interface or other resources should have its own compatible and schema. As L1 caches are described within CPU nodes, this binding only applies to L2 and higher level caches. maintainers: - Rob Herring select: properties: compatible: const: cache required: - compatible allOf: - $ref: cache-controller.yaml# properties: $nodename: pattern: 'cache' compatible: const: cache power-domains: maxItems: 1 patternProperties: '^l[3-9]-cache$': type: object description: Caches can have the next level cache as a child node required: - cache-level # In practice, all level 2 and higher caches are unified. - cache-unified unevaluatedProperties: false ... dt-schema-2025.08/dtschema/schemas/chosen.yaml000066400000000000000000000243361504414563000211270ustar00rootroot00000000000000# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-clause # Copyright 2014,2018 Linaro Ltd. # # Descriptions based on chosen.txt from Linux kernel # Copyright 2017 Kees Cook # Copyright 2017 Jonathan Neuschäfer # Copyright ARM Ltd 2017 # Copyright 2015 Freescale Semiconductor, Inc. %YAML 1.2 --- $id: http://devicetree.org/schemas/chosen.yaml# $schema: http://devicetree.org/meta-schemas/core.yaml# title: /chosen Node maintainers: - Devicetree Specification Mailing List description: The chosen node does not represent a real device, but serves as a place for passing data between firmware and the operating system, like boot arguments. Data in the chosen node does not represent the hardware. properties: $nodename: const: chosen "#address-cells": true "#size-cells": true ranges: true bootargs: $ref: types.yaml#/definitions/string bootsource: $ref: types.yaml#/definitions/string description: This property represents the full path to the node representing the device the BootROM used to load the initial boot program, e.g. / { chosen { bootsource = "/mmc@ff390000"; }; }; If the initial boot program is split into multiple stages, this represents the storage medium or device (e.g. used by fastboot) from which the very first stage was loaded by the BootROM. It may differ from the device from which later stages of the boot program or client program are loaded from, as this property isn't meant to represent those devices. A later stage of the boot program, or the client program, may use this information to favor the device in this property over others for loading later stages, or know the storage medium to flash an update to. kaslr-seed: $ref: types.yaml#/definitions/uint64 description: This property is used when booting with CONFIG_RANDOMIZE_BASE as the entropy used to randomize the kernel image base address location. Since it is used directly, this value is intended only for KASLR, and should not be used for other purposes (as it may leak information about KASLR offsets). It is parsed as a u64 value, e.g. /{ chosen { kaslr-seed = <0xfeedbeef 0xc0def00d>; }; }; Note that if this property is set from UEFI (or a bootloader in EFI mode) when EFI_RNG_PROTOCOL is supported, it will be overwritten by the Linux EFI stub (which will populate the property itself, using EFI_RNG_PROTOCOL). rng-seed: $ref: types.yaml#/definitions/uint8-array description: This property served as an entropy to add device randomness. It is parsed as a byte array, e.g. /{ chosen { rng-seed = /bits/ 8 <0x31 0x95 0x1b 0x3c 0xc9 0xfa ...>; }; }; This random value should be provided by bootloader. linux,booted-from-kexec: type: boolean description: This property is set (currently only on PowerPC, and only needed on book3e) by some versions of kexec-tools to tell the new kernel that it is being booted by kexec, as the booting environment may differ (e.g. a different secondary CPU release mechanism). linux,elfcorehdr: $ref: types.yaml#/definitions/address maxItems: 1 description: | This property holds the memory range, the address and the size, of the elf core header which mainly describes the panicked kernel\'s memory layout as PT_LOAD segments of elf format. / { chosen { linux,elfcorehdr = <0x9 0xfffff000 0x0 0x800>; }; }; While this property does not represent a real hardware, the address and the size are expressed in #address-cells and #size-cells, respectively, of the root node. linux,usable-memory-range: $ref: types.yaml#/definitions/address maxItems: 1 description: | This property holds a base address and size, describing a limited region in which memory may be considered available for use by the kernel. Memory outside of this range is not available for use. This property describes a limitation: memory within this range is only valid when also described through another mechanism that the kernel would otherwise use to determine available memory (e.g. memory nodes or the EFI memory map). Valid memory may be sparse within the range. / { chosen { linux,usable-memory-range = <0x9 0xf0000000 0x0 0x10000000>; }; }; The main usage is for crash dump kernel to identify its own usable memory and exclude, at its boot time, any other memory areas that are part of the panicked kernel\'s memory. While this property does not represent a real hardware, the address and the size are expressed in #address-cells and #size-cells, respectively, of the root node. linux,initrd-start: $ref: types.yaml#/definitions/address maxItems: 1 description: These properties hold the physical start and end address of an initrd that\'s loaded by the bootloader. Note that linux,initrd-start is inclusive, but linux,initrd-end is exclusive. linux,initrd-end: $ref: types.yaml#/definitions/address maxItems: 1 description: These properties hold the physical start and end address of an initrd that\'s loaded by the bootloader. Note that linux,initrd-start is inclusive, but linux,initrd-end is exclusive. linux,pci-probe-only: $ref: types.yaml#/definitions/uint32 enum: [ 0, 1 ] description: Optional property which takes a single-cell argument. If '0', then Linux will assign devices in its usual manner, otherwise it will not try to assign devices and instead use them as they are configured already. stdout-path: $ref: types.yaml#/definitions/string pattern: "^[a-zA-Z0-9@/,+\\-._]*(:[0-9]*[noe]?[78]?[r]?)?$" description: | Device trees may specify the device to be used for boot console output with a stdout-path property under /chosen, as described in the Devicetree Specification, e.g. / { chosen { stdout-path = "/serial@f00:115200"; }; serial@f00 { compatible = "vendor,some-uart"; reg = <0xf00 0x10>; }; }; If the character ":" is present in the value, this terminates the path. The meaning of any characters following the ":" is device-specific, and must be specified in the relevant binding documentation. For UART devices, the preferred binding is a string in the form: {{{}}} where baud - baud rate in decimal parity - 'n' (none), 'o', (odd) or 'e' (even) bits - number of data bits flow - 'r' (rts) For example: 115200n8r Implementation note: Linux will look for the property "linux,stdout-path" or on PowerPC "stdout" if "stdout-path" is not found. However, the "linux,stdout-path" and "stdout" properties are deprecated. New platforms should only use the "stdout-path" property. linux,ima-kexec-buffer: $ref: types.yaml#/definitions/address maxItems: 1 description: | This property(currently used by powerpc, arm64) holds the memory range, "the address and the size", of the Integrity Measurement Architecture(IMA) measurement logs that are being carried over to the new kernel. / { chosen { linux,ima-kexec-buffer = <0x9 0x82000000 0x0 0x00008000>; }; }; This property does not represent real hardware, but the memory allocated for carrying the IMA measurement logs. The address and the size are expressed in #address-cells and #size-cells, respectively of the root node. linux,uefi-system-table: $ref: types.yaml#/definitions/uint64 description: Physical address of the UEFI System Table. linux,uefi-mmap-start: $ref: types.yaml#/definitions/uint64 description: Physical address of the UEFI memory map, populated by the UEFI GetMemoryMap() call. linux,uefi-mmap-size: $ref: types.yaml#/definitions/uint32 description: Size in bytes of the UEFI memory map pointed to by linux,uefi-mmap-start. linux,uefi-mmap-desc-size: $ref: types.yaml#/definitions/uint32 description: Size in bytes of each entry in the UEFI memory map. linux,uefi-mmap-desc-ver: $ref: types.yaml#/definitions/uint32 description: Version of the mmap descriptor format. linux,kho-fdt: $ref: types.yaml#/definitions/address maxItems: 1 description: | This property holds the memory range, the address and the size, of the KHO state blob carrying system states passed from the previous kernel across kexec. / { chosen { linux,booted-from-kexec; linux,kho-scratch = <0x00 0xb4df0000 0x00 0x30>; linux,kho-fdt = <0x00 0xb4e00000 0x00 0xa00000>; }; }; This property does not represent a real hardware. The address and the size are expressed in #address-cells and #size-cells, respectively, of the root node. linux,kho-scratch: $ref: types.yaml#/definitions/address maxItems: 1 description: | This property holds the memory range, the address and the size, of the KHO scratch region information passed from the previous kernel across kexec. This property does not represent a real hardware. The address and the size are expressed in #address-cells and #size-cells, respectively, of the root node. u-boot,bootconf: $ref: types.yaml#/definitions/string description: This property can be used by U-Boot to pass the selected configuration unit name of the booted image down to the operating system. u-boot,version: $ref: types.yaml#/definitions/string pattern: "^20[0-9]{2}\\.[0-9]{2}.*$" description: This property is used by U-Boot to pass its version down to the operating system. patternProperties: "^framebuffer": true additionalProperties: false dt-schema-2025.08/dtschema/schemas/clock/000077500000000000000000000000001504414563000200475ustar00rootroot00000000000000dt-schema-2025.08/dtschema/schemas/clock/clock.yaml000066400000000000000000000150661504414563000220360ustar00rootroot00000000000000# SPDX-License-Identifier: BSD-2-Clause # Copyright 2018 Linaro Ltd. # Copyright 2012 Secret Lab Technologies Ltd. %YAML 1.2 --- $id: http://devicetree.org/schemas/clock/clock.yaml# $schema: http://devicetree.org/meta-schemas/base.yaml# title: Clock Common Properties maintainers: - Michael Turquette - Stephen Boyd description: | Sources of clock signal can be represented by any node in the device tree. Those nodes are designated as clock providers. Clock consumer nodes use a phandle and clock specifier pair to connect clock provider outputs to clock inputs. Similar to the gpio specifiers, a clock specifier is an array of zero, one or more cells identifying the clock output on a device. The length of a clock specifier is defined by the value of a #clock-cells property in the clock provider node. Assigned clock parents and rates -------------------------------- Some platforms may require initial configuration of default parent clocks and clock frequencies. Such a configuration can be specified in a device tree node through assigned-clocks, assigned-clock-parents and assigned-clock-rates properties. The assigned-clock-parents property should contain a list of parent clocks in the form of a phandle and clock specifier pair and the assigned-clock-rates property should contain a list of frequencies in Hz. Both these properties should correspond to the clocks listed in the assigned-clocks property. To skip setting parent or rate of a clock its corresponding entry should be set to 0, or can be omitted if it is not followed by any non-zero entry. serial@a000 { compatible = "fsl,imx-uart"; reg = <0xa000 0x1000>; ... clocks = <&osc 0>, <&pll 1>; clock-names = "baud", "register"; assigned-clocks = <&clkcon 0>, <&pll 2>; assigned-clock-parents = <&pll 2>; assigned-clock-rates = <0>, <460800>; }; In this example the <&pll 2> clock is set as parent of clock <&clkcon 0> and the <&pll 2> clock is assigned a frequency value of 460800 Hz. Configuring a clock's parent and rate through the device node that consumes the clock can be done only for clocks that have a single user. Specifying conflicting parent or rate configuration in multiple consumer nodes for a shared clock is forbidden. Configuration of common clocks, which affect multiple consumer devices can be similarly specified in the clock provider node. # always select the core schema select: true properties: # Legacy clock properties clock-frequency: description: Legacy property for single, fixed frequency clocks anyOf: - $ref: /schemas/types.yaml#/definitions/uint32 - $ref: /schemas/types.yaml#/definitions/uint64 bus-frequency: description: Legacy property for fixed bus frequencies $ref: /schemas/types.yaml#/definitions/uint32 # Provider properties "#clock-cells": description: Number of cells in a clock specifier; Typically 0 for nodes with a single clock output and 1 for nodes with multiple clock outputs. clock-output-names: description: | Recommended to be a list of strings of clock output signal names indexed by the first cell in the clock specifier. However, the meaning of clock-output-names is domain specific to the clock provider, and is only provided to encourage using the same meaning for the majority of clock providers. This format may not work for clock providers using a complex clock specifier format. In those cases it is recommended to omit this property and create a binding specific names property. Clock consumer nodes must never directly reference the provider\'s clock-output-names property. clock-indices: $ref: /schemas/types.yaml#/definitions/uint32-array description: If the identifying number for the clocks in the node is not linear from zero, then this allows the mapping of identifiers into the clock-output-names array. # Consumer properties clocks: anyOf: - type: object # for nodes named 'clocks' - $ref: /schemas/types.yaml#/definitions/phandle-array description: | List of phandle and clock specifier pairs, one pair for each clock input to the device. Note: if the clock provider specifies '0' for #clock-cells, then only the phandle portion of the pair will appear. clock-names: $ref: /schemas/types.yaml#/definitions/string-array description: List of clock input name strings sorted in the same order as the clocks property. Consumers drivers will use clock-names to match clock input names with clocks specifiers. clock-ranges: type: boolean description: Empty property indicating that child nodes can inherit named clocks from this node. Useful for bus nodes to provide a clock to their children. assigned-clocks: $ref: /schemas/types.yaml#/definitions/phandle-array assigned-clock-parents: $ref: /schemas/types.yaml#/definitions/phandle-array assigned-clock-rates: $ref: /schemas/types.yaml#/definitions/uint32-array assigned-clock-rates-u64: $ref: /schemas/types.yaml#/definitions/uint64-array assigned-clock-sscs: $ref: /schemas/types.yaml#/definitions/uint32-matrix items: items: - description: The modulation frequency - description: The modulation depth in permyriad - description: The modulation method, down-spread(3), up-spread(2), center-spread(1), no-spread(0) minimum: 0 maximum: 3 protected-clocks: $ref: /schemas/types.yaml#/definitions/uint32-array description: Some platforms or firmwares may not fully expose all the clocks to the OS, such as in situations where those clks are used by drivers running in ARM secure execution levels. Such a configuration can be specified in devicetree with the protected-clocks property in the form of a clock specifier list. This property should only be specified in the node that is providing the clocks being protected. dependentRequired: clock-names: [clocks] clock-output-names: ["#clock-cells"] clock-indices: [clock-output-names] clock-ranges: [clocks] assigned-clock-parents: [assigned-clocks] assigned-clock-rates: [assigned-clocks] assigned-clock-rates-u64: [assigned-clocks] assigned-clock-sscs: [assigned-clocks] protected-clocks: ["#clock-cells"] dependentSchemas: assigned-clocks: anyOf: - required: [clocks] - required: ["#clock-cells"] additionalProperties: true dt-schema-2025.08/dtschema/schemas/cpu-map.yaml000066400000000000000000000167511504414563000212140ustar00rootroot00000000000000# SPDX-License-Identifier: GPL-2.0 OR BSD-2-clause # Copyright 2013,2023 Arm, Ltd. # # Based on cpu-topology.txt binding from Linux kernel %YAML 1.2 --- $id: http://devicetree.org/schemas/cpu-map.yaml# $schema: http://devicetree.org/meta-schemas/core.yaml# title: CPU Topology nodes maintainers: - devicetree-spec@vger.kernel.org description: | In a SMP system, the hierarchy of CPUs is defined through three entities that are used to describe the layout of physical CPUs in the system: - socket - cluster - core - thread The bottom hierarchy level sits at core or thread level depending on whether symmetric multi-threading (SMT) is supported or not. For instance in a system where CPUs support SMT, "cpu" nodes represent all threads existing in the system and map to the hierarchy level "thread" above. In systems where SMT is not supported "cpu" nodes represent all cores present in the system and map to the hierarchy level "core" above. CPU topology bindings allow one to associate cpu nodes with hierarchical groups corresponding to the system hierarchy; syntactically they are defined as device tree nodes. Currently, only ARM/RISC-V intend to use this cpu topology binding but it may be used for any other architecture as well. The cpu nodes, as per bindings defined in [4], represent the devices that correspond to physical CPUs and are to be mapped to the hierarchy levels. A topology description containing phandles to cpu nodes that are not compliant with bindings standardized in [4] is therefore considered invalid. =========================================== 2 - cpu-map node =========================================== The ARM/RISC-V CPU topology is defined within the cpu-map node, which is a direct child of the cpus node and provides a container where the actual topology nodes are listed. The cpu-map node can only contain 4 types of child nodes: - socket node - cluster node - core node - thread node The nodes describing the CPU topology (socket/cluster/core/thread) can only be defined within the cpu-map node and every core/thread in the system must be defined within the topology. Any other configuration is invalid and therefore must be ignored. =========================================== 2.1 - cpu-map child nodes naming convention =========================================== cpu-map child nodes must follow a naming convention where the node name must be "socketN", "clusterN", "coreN", "threadN" depending on the node type (ie socket/cluster/core/thread) (where N = {0, 1, ...} is the node number; nodes which are siblings within a single common parent node must be given a unique and sequential N value, starting from 0). cpu-map child nodes which do not share a common parent node can have the same name (ie same number N as other cpu-map child nodes at different device tree levels) since name uniqueness will be guaranteed by the device tree hierarchy. =========================================== [1] ARM Linux kernel documentation Documentation/devicetree/bindings/arm/cpus.yaml [2] Devicetree NUMA binding description Documentation/devicetree/bindings/numa.txt [3] RISC-V Linux kernel documentation Documentation/devicetree/bindings/riscv/cpus.yaml [4] https://www.devicetree.org/specifications/ $defs: cluster: type: object oneOf: - additionalProperties: false patternProperties: '^cluster[0-9]+$': $ref: '#/$defs/cluster' - additionalProperties: false patternProperties: '^core[0-9]+$': $ref: '#/$defs/core' core: type: object oneOf: - additionalProperties: false patternProperties: '^thread[0-9]+$': $ref: '#/$defs/core' - additionalProperties: false properties: cpu: $ref: /schemas/types.yaml#/definitions/phandle required: - cpu properties: $nodename: const: cpu-map patternProperties: '^(socket|cluster)[0-9]+$': $ref: '#/$defs/cluster' description: | The cpu-map node's child nodes can be: - one or more cluster nodes or - one or more socket nodes in a multi-socket system. A system can contain single or multiple physical socket. The association of sockets and NUMA nodes is beyond the scope of this binding, please refer [2] for NUMA bindings. additionalProperties: false examples: - | # 16-cpu system, two clusters of clusters in a single physical socket cpu-map { socket0 { cluster0 { cluster0 { core0 { thread0 { cpu = <&CPU0>; }; thread1 { cpu = <&CPU1>; }; }; core1 { thread0 { cpu = <&CPU2>; }; thread1 { cpu = <&CPU3>; }; }; }; cluster1 { core0 { thread0 { cpu = <&CPU4>; }; thread1 { cpu = <&CPU5>; }; }; core1 { thread0 { cpu = <&CPU6>; }; thread1 { cpu = <&CPU7>; }; }; }; }; cluster1 { cluster0 { core0 { thread0 { cpu = <&CPU8>; }; thread1 { cpu = <&CPU9>; }; }; core1 { thread0 { cpu = <&CPU10>; }; thread1 { cpu = <&CPU11>; }; }; }; cluster1 { core0 { thread0 { cpu = <&CPU12>; }; thread1 { cpu = <&CPU13>; }; }; core1 { thread0 { cpu = <&CPU14>; }; thread1 { cpu = <&CPU15>; }; }; }; }; }; }; - | # 2 Clusters of 4 cores each with no SMT cpu-map { cluster0 { core0 { cpu = <&CPU0>; }; core1 { cpu = <&CPU1>; }; core2 { cpu = <&CPU2>; }; core3 { cpu = <&CPU3>; }; }; cluster1 { core0 { cpu = <&CPU4>; }; core1 { cpu = <&CPU5>; }; core2 { cpu = <&CPU6>; }; core3 { cpu = <&CPU7>; }; }; }; ... dt-schema-2025.08/dtschema/schemas/cpu.yaml000066400000000000000000000102211504414563000204230ustar00rootroot00000000000000# SPDX-License-Identifier: GPL-2.0 OR BSD-2-clause # Copyright (C) 2018-2019 SiFive, Inc. # # Description text is from the Devicetree Specification at # https://www.devicetree.org/specifications/ # which is # Copyright 2008,2011 Power.org, Inc. # Copyright 2008,2011 Freescale Semiconductor, Inc. # Copyright 2008,2011 International Business Machines Corporation # Copyright 2016,2017 Linaro,Ltd. # Copyright 2016,2017 Arm,Ltd. # %YAML 1.2 --- $id: http://devicetree.org/schemas/cpu.yaml# $schema: http://devicetree.org/meta-schemas/base.yaml# title: CPU node common properties maintainers: - Devicetree Specification Mailing List description: |+ In Devicetree data files, the layout of CPUs is described in the "cpus" node. This node in turn contains a number of subnodes representing CPUs, which define properties for every cpu. Bindings for CPU nodes follow the Devicetree Specification, available from: https://www.devicetree.org/specifications/ select: false allOf: - $ref: cache-controller.yaml# properties: device_type: const: cpu reg: description: Defines a unique CPU/thread ID for the CPU/threads represented by the CPU node. compatible: true '#cooling-cells': const: 2 clock-frequency: description: Specifies the current clock speed of the CPU in Hertz. clocks: true clock-names: true cpu-supply: true timebase-frequency: oneOf: - $ref: /schemas/types.yaml#/definitions/uint32 - $ref: /schemas/types.yaml#/definitions/uint64 minimum: 1 description: Specifies the current frequency at which the timebase and the decrementer registers are updated (in Hertz). status: $ref: types.yaml#/definitions/string enum: [ okay, disabled, fail ] description: A standard property describing the state of a CPU. A CPU may be running ("okay"), in a quiescent state ("disabled") or be not operational or not exist ("fail"). enable-method: $ref: /schemas/types.yaml#/definitions/string-array description: Describes the method by which a CPU in a disabled state is enabled. This property is required for CPUs with a status property with a value of "disabled". The value consists of one or more strings that define the method to release this CPU. If a client program recognizes any of the methods, it may use it. cpu-release-addr: oneOf: - $ref: /schemas/types.yaml#/definitions/uint64 - $ref: /schemas/types.yaml#/definitions/uint32 deprecated: true # Needed for some 32-bit Arm systems description: This value specifies the physical address of a spin table entry that releases a secondary CPU from its spin loop. cache-op-block-size: $ref: /schemas/types.yaml#/definitions/uint32 description: Specifies the block size in bytes upon which cache block instructions operate. Required if different than the L1 cache block size. reservation-granule-size: $ref: /schemas/types.yaml#/definitions/uint32 description: Specifies the reservation granule size supported by this processor in bytes. numa-node-id: true mmu-type: $ref: /schemas/types.yaml#/definitions/string description: Specifies the CPU's MMU type. operating-points-v2: true tlb-split: $ref: /schemas/types.yaml#/definitions/flag description: If present, specifies that the TLB has a split configuration, with separate TLBs for instructions and data. If absent, specifies that the TLB has a unified configuration. Required for a CPU with a TLB in a split configuration. l2-cache: oneOf: - type: object - $ref: /schemas/types.yaml#/definitions/phandle deprecated: true patternProperties: "^(i-|d-|)tlb-(size|sets)$": $ref: /schemas/types.yaml#/definitions/uint32 minimum: 1 anyOf: - required: - device_type - required: - reg - required: - compatible dependencies: cpu-release-addr: [ enable-method ] d-tlb-size: [ tlb-split ] d-tlb-sets: [ tlb-split ] i-tlb-size: [ tlb-split ] i-tlb-sets: [ tlb-split ] additionalProperties: true ... dt-schema-2025.08/dtschema/schemas/cpus.yaml000066400000000000000000000031651504414563000206170ustar00rootroot00000000000000# SPDX-License-Identifier: GPL-2.0 OR BSD-2-clause # Copyright (C) 2018-2019 SiFive, Inc. # # Description text is from the Devicetree Specification at # https://www.devicetree.org/specifications/ # which is # Copyright 2008,2011 Power.org, Inc. # Copyright 2008,2011 Freescale Semiconductor, Inc. # Copyright 2008,2011 International Business Machines Corporation # Copyright 2016,2017 Linaro,Ltd. # Copyright 2016,2017 Arm,Ltd. # %YAML 1.2 --- $id: http://devicetree.org/schemas/cpus.yaml# $schema: http://devicetree.org/meta-schemas/base.yaml# title: Common CPU Nodes properties maintainers: - Devicetree Specification Mailing List description: |+ In Devicetree data files, the layout of CPUs is described in the "cpus" node. This node in turn contains a number of subnodes representing CPUs, which define properties for every cpu. Bindings for CPU nodes follow the Devicetree Specification, available from: https://www.devicetree.org/specifications/ properties: $nodename: const: cpus description: A /cpus node is required for all Devicetrees. It does not represent a real device in the system, but acts as a container for child "cpu" nodes which represent the systems' CPUs. '#address-cells': minimum: 1 description: The value specifies how many cells each element of the reg property array takes in children of this node. '#size-cells': const: 0 cpu-map: $ref: /schemas/cpu-map.yaml# patternProperties: '^cpu@[0-9a-f]+$': $ref: cpu.yaml# required: - '#address-cells' - '#size-cells' additionalProperties: true ... dt-schema-2025.08/dtschema/schemas/dma/000077500000000000000000000000001504414563000175155ustar00rootroot00000000000000dt-schema-2025.08/dtschema/schemas/dma/dma.yaml000066400000000000000000000012371504414563000211450ustar00rootroot00000000000000# SPDX-License-Identifier: BSD-2-Clause # Copyright 2019 Linaro Ltd. %YAML 1.2 --- $id: http://devicetree.org/schemas/dma/dma.yaml# $schema: http://devicetree.org/meta-schemas/base.yaml# title: DMA Consumer Common Properties maintainers: - Rob Herring # always select the core schema select: true properties: dmas: $ref: /schemas/types.yaml#/definitions/phandle-array dma-names: anyOf: - uniqueItems: true - items: # Hack around Renesas bindings which repeat entries to support # multiple possible DMA providers enum: [rx, tx] dependencies: dma-names: [ dmas ] additionalProperties: true dt-schema-2025.08/dtschema/schemas/dt-core.yaml000066400000000000000000000050331504414563000211760ustar00rootroot00000000000000# SPDX-License-Identifier: BSD-2-Clause # Copyright 2018 Linaro Ltd. # Copyright 2018 Arm Ltd. %YAML 1.2 --- $id: http://devicetree.org/schemas/dt-core.yaml# $schema: http://devicetree.org/meta-schemas/base.yaml# title: Core Devicetree Properties description: Schema for core devicetree bindings maintainers: - Rob Herring # always select the core schema select: true properties: $nodename: $ref: types.yaml#/definitions/string compatible: $ref: types.yaml#/definitions/string-array items: # Keep in sync with make_compatible_schema() pattern: "^[a-zA-Z0-9][a-zA-Z0-9,+\\-._/]+$" cpu: description: Phandles to a CPU node associated with the referring node. oneOf: - type: object - $ref: types.yaml#/definitions/phandle cpus: description: Phandles to CPU nodes associated with the referring node. oneOf: - type: object - $ref: types.yaml#/definitions/phandle-array items: maxItems: 1 label: $ref: types.yaml#/definitions/string dma-coherent: $ref: types.yaml#/definitions/flag dma-noncoherent: $ref: types.yaml#/definitions/flag firmware-name: $ref: types.yaml#/definitions/string-array description: The filename for a device's firmware file. It is typically a single entry, but some devices have multiple firmware files. It can also be just a stem name used to construct the full firmware filename(s). secure-status: $ref: types.yaml#/definitions/string enum: [ okay, disabled, reserved, fail ] status: oneOf: - type: object - $ref: types.yaml#/definitions/string enum: [ okay, disabled, reserved, fail, fail-needs-probe ] phandle: $ref: types.yaml#/definitions/uint32 patternProperties: "^#.*-cells$": $ref: types.yaml#/definitions/uint32 maximum: 8 ".*-names$": $ref: types.yaml#/definitions/non-unique-string-array ".*-supply$": oneOf: - type: object - $ref: types.yaml#/definitions/phandle # property and node namespace overlaps. Catch both here "^[a-zA-Z0-9][a-zA-Z0-9#,+\\-._]{0,63}$": type: [object, integer, array, boolean, 'null'] # Anything with a '@' is definitely a node "^[a-zA-Z0-9][a-zA-Z0-9,+\\-._]{0,63}@[0-9a-fA-F]+(,[0-9a-fA-F]+)*$": type: object # Anything beginnning and ending with '__' is a generated node "^__.*__$": type: object # Anything with a '#' is single cell number "^#[a-zA-Z0-9,+\\-._]{0,63}$": $ref: types.yaml#/definitions/uint32 additionalProperties: false ... dt-schema-2025.08/dtschema/schemas/gpio/000077500000000000000000000000001504414563000177125ustar00rootroot00000000000000dt-schema-2025.08/dtschema/schemas/gpio/gpio-consumer.yaml000066400000000000000000000014101504414563000233610ustar00rootroot00000000000000# SPDX-License-Identifier: BSD-2-Clause # Copyright 2018 Linaro Ltd. $id: http://devicetree.org/schemas/gpio/gpio-consumer.yaml# $schema: http://devicetree.org/meta-schemas/base.yaml# title: GPIO Consumer Common Properties description: Schema for GPIO consumer devicetree bindings maintainers: - Rob Herring # do not select this schema for GPIO hogs select: properties: gpio-hog: false properties: gpios: $ref: /schemas/types.yaml#/definitions/phandle-array gpio: # 'gpio' can appear as a property or node name oneOf: - type: object - $ref: /schemas/types.yaml#/definitions/phandle-array patternProperties: "(? # select this schema for GPIO hogs select: properties: gpio-hog: true required: - gpio-hog properties: $nodename: pattern: "-hog(-[0-9]+)?$" gpio-hog: $ref: /schemas/types.yaml#/definitions/flag gpios: $ref: /schemas/types.yaml#/definitions/uint32-matrix input: $ref: /schemas/types.yaml#/definitions/flag line-name: $ref: /schemas/types.yaml#/definitions/string output-high: $ref: /schemas/types.yaml#/definitions/flag output-low: $ref: /schemas/types.yaml#/definitions/flag required: - gpio-hog - gpios oneOf: - required: - input - required: - output-high - required: - output-low additionalProperties: false dt-schema-2025.08/dtschema/schemas/gpio/gpio-nexus-node.yaml000066400000000000000000000014341504414563000236210ustar00rootroot00000000000000# SPDX-License-Identifier: BSD-2-Clause # Copyright Ayush Singh $id: http://devicetree.org/schemas/gpio/gpio-nexus-node.yaml# $schema: http://devicetree.org/meta-schemas/base.yaml# title: GPIO Nexus node properties description: Schema for nexus node devicetree bindings maintainers: - Ayush Singh # always select the core schema select: true properties: "#gpio-cells": true gpio-map: $ref: /schemas/types.yaml#/definitions/uint32-matrix gpio-map-mask: $ref: /schemas/types.yaml#/definitions/uint32-array gpio-map-pass-thru: $ref: /schemas/types.yaml#/definitions/uint32-array dependentRequired: gpio-map: ['#gpio-cells'] 'gpio-map-mask': [ gpio-map ] 'gpio-map-pass-thru': [ gpio-map ] additionalProperties: true dt-schema-2025.08/dtschema/schemas/gpio/gpio.yaml000066400000000000000000000071501504414563000215370ustar00rootroot00000000000000# SPDX-License-Identifier: BSD-2-Clause # Copyright 2018 Linaro Ltd. $id: http://devicetree.org/schemas/gpio/gpio.yaml# $schema: http://devicetree.org/meta-schemas/base.yaml# title: GPIO Controller Common Properties description: | Every GPIO controller node must contain both an empty "gpio-controller" property, and a #gpio-cells integer property, which indicates the number of cells in a gpio-specifier. Some system-on-chips (SoCs) use the concept of GPIO banks. A GPIO bank is an instance of a hardware IP core on a silicon die, usually exposed to the programmer as a coherent range of I/O addresses. Usually each such bank is exposed in the device tree as an individual gpio-controller node, reflecting the fact that the hardware was synthesized by reusing the same IP block a few times over. maintainers: - Rob Herring # always select the core schema select: true properties: "#gpio-cells": true gpio-controller: $ref: /schemas/types.yaml#/definitions/flag gpio-line-names: $ref: /schemas/types.yaml#/definitions/non-unique-string-array description: > An array of strings defining the names of the GPIO lines going out of the GPIO controller. This name should be the most meaningful producer name for the system, such as a rail name indicating the usage. Package names such as pin name are discouraged: such lines have opaque names (since they are by definition generic purpose) and such names are usually not very helpful. For example "MMC-CD", "Red LED Vdd" and "ethernet reset" are reasonable line names as they describe what the line is used for. "GPIO0" is not a good name to give to a GPIO line. Placeholders are discouraged: rather use the "" (blank string) if the use of the GPIO line is undefined in your design. The names are assigned starting from line offset 0 from left to right from the passed array. An incomplete array (where the number of passed named are less than ngpios) will still be used up until the last provided valid line index. ngpios: $ref: /schemas/types.yaml#/definitions/uint32 description: > Indicates the number of in-use slots of available slots for GPIOs. The typical example is something like this: the hardware register is 32 bits wide, but only 18 of the bits have a physical counterpart. The driver is generally written so that all 32 bits can be used, but the IP block is reused in a lot of designs, some using all 32 bits, some using 18 and some using 12. In this case, setting "ngpios = <18>;" informs the driver that only the first 18 GPIOs, at local offset 0 .. 17, are in use. If these GPIOs do not happen to be the first N GPIOs at offset 0...N-1, an additional set of tuples is needed to specify which GPIOs are unusable, with the gpio-reserved-ranges binding. gpio-reserved-ranges: $ref: /schemas/types.yaml#/definitions/uint32-matrix items: minItems: 2 maxItems: 2 description: Indicates the start and size of the GPIOs that can't be used. gpio-ranges: $ref: /schemas/types.yaml#/definitions/phandle-array items: items: - description: pin controller phandle - description: GPIO controller offset - description: pin controller offset - description: number of pins dependencies: gpio-controller: ['#gpio-cells'] gpio-line-names: ['#gpio-cells', gpio-controller] ngpios: ['#gpio-cells', gpio-controller] gpio-reserved-ranges: ['#gpio-cells', gpio-controller] gpio-ranges: ['#gpio-cells', gpio-controller] additionalProperties: true dt-schema-2025.08/dtschema/schemas/graph.yaml000066400000000000000000000140261504414563000207440ustar00rootroot00000000000000# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) %YAML 1.2 --- $id: http://devicetree.org/schemas/graph.yaml# $schema: http://devicetree.org/meta-schemas/base.yaml# title: Device Graphs description: | The hierarchical organisation of the device tree is well suited to describe control flow to devices, but there can be more complex connections between devices that work together to form a logical compound device, following an arbitrarily complex graph. There already is a simple directed graph between devices tree nodes using phandle properties pointing to other nodes to describe connections that can not be inferred from device tree parent-child relationships. The device tree graph bindings described herein abstract more complex devices that can have multiple specifiable ports, each of which can be linked to one or more ports of other devices. These common bindings do not contain any information about the direction or type of the connections, they just map their existence. Specific properties may be described by specialized bindings depending on the type of connection. To see how this binding applies to video pipelines, for example, see Documentation/devicetree/bindings/media/video-interfaces.txt. Here the ports describe data interfaces, and the links between them are the connecting data buses. A single port with multiple connections can correspond to multiple devices being connected to the same physical bus. maintainers: - Philipp Zabel select: false $defs: endpoint-base: type: object properties: reg: maxItems: 1 remote-endpoint: description: | phandle to an 'endpoint' subnode of a remote device node. $ref: /schemas/types.yaml#/definitions/phandle port-base: type: object description: If there is more than one endpoint node or 'reg' property present in endpoint nodes then '#address-cells' and '#size-cells' properties are required. properties: "#address-cells": const: 1 "#size-cells": const: 0 reg: maxItems: 1 endpoint: type: object patternProperties: "^endpoint@[0-9a-f]+$": $ref: "#/$defs/endpoint-base" required: - reg properties: endpoint: $ref: "#/$defs/endpoint-base" unevaluatedProperties: false port: $ref: "#/$defs/port-base" unevaluatedProperties: false patternProperties: "^endpoint(@[0-9a-f]+)?$": $ref: "#/properties/endpoint" ports: type: object description: If there is more than one port node or 'reg' property present in port nodes then '#address-cells' and '#size-cells' properties are required. In such cases all port nodes can be grouped under 'ports' independently from any other child device nodes a device might have. properties: "#address-cells": const: 1 "#size-cells": const: 0 port: type: object patternProperties: "^port@[0-9a-f]+$": type: object required: - reg oneOf: - required: - port - required: - "#address-cells" - "#size-cells" additionalProperties: false additionalProperties: true examples: # Organisation of ports and endpoints: # # Ports are described by child 'port' nodes contained in the device node. # Each port node contains an 'endpoint' subnode for each remote device port # connected to this port. If a single port is connected to more than one # remote device, an 'endpoint' child node must be provided for each link. # If more than one port is present in a device node or there is more than # one endpoint at a port, or a port node needs to be associated with a # selected hardware interface, a common scheme using '#address-cells', # '#size-cells' and 'reg' properties is used to number the nodes. - | device { #address-cells = <1>; #size-cells = <0>; port@0 { #address-cells = <1>; #size-cells = <0>; reg = <0>; endpoint@0 { reg = <0>; // ... }; endpoint@1 { reg = <1>; // ... }; }; port@1 { reg = <1>; endpoint { // ... }; }; }; # All 'port' nodes can be grouped under an optional 'ports' node, which # allows to specify #address-cells, #size-cells properties for the 'port' # nodes independently from any other child device nodes a device might # have. - | device { // ... ports { #address-cells = <1>; #size-cells = <0>; port@0 { #address-cells = <1>; #size-cells = <0>; reg = <0>; // ... endpoint@0 { reg = <0>; // ... }; endpoint@1 { reg = <1>; // ... }; }; port@1 { #address-cells = <1>; #size-cells = <0>; reg = <1>; // ... }; }; }; # Links between endpoints: # # Each endpoint should contain a 'remote-endpoint' phandle property that # points to the corresponding endpoint in the port of the remote device. # In turn, the remote endpoint should contain a 'remote-endpoint' property. # If it has one, it must not point to anything other than the local endpoint. # Two endpoints with their 'remote-endpoint' phandles pointing at each other # form a link between the containing ports. - | device-1 { port { device_1_output: endpoint { remote-endpoint = <&device_2_input>; }; }; }; device-2 { port { device_2_input: endpoint { remote-endpoint = <&device_1_output>; }; }; }; ... dt-schema-2025.08/dtschema/schemas/hwlock/000077500000000000000000000000001504414563000202435ustar00rootroot00000000000000dt-schema-2025.08/dtschema/schemas/hwlock/hwlock-consumer.yaml000066400000000000000000000011201504414563000242410ustar00rootroot00000000000000# SPDX-License-Identifier: BSD-2-Clause # Copyright 2019 ARM Ltd. # Copyright 2019 Linaro Ltd. %YAML 1.2 --- $id: http://devicetree.org/schemas/hwlock/hwlock-consumer.yaml# $schema: http://devicetree.org/meta-schemas/base.yaml# title: H/W Locks Consumer Common Properties maintainers: - Rob Herring # always select the core schema select: true properties: hwlocks: $ref: /schemas/types.yaml#/definitions/phandle-array hwlock-names: $ref: /schemas/types.yaml#/definitions/string-array dependencies: hwlock-names: [ hwlocks ] additionalProperties: true dt-schema-2025.08/dtschema/schemas/i2c/000077500000000000000000000000001504414563000174315ustar00rootroot00000000000000dt-schema-2025.08/dtschema/schemas/i2c/i2c-controller.yaml000066400000000000000000000147701504414563000231640ustar00rootroot00000000000000# SPDX-License-Identifier: BSD-2-Clause # Copyright 2018 Linaro Ltd. # Copyright 2015,2020 Wolfram Sang # Copyright 2022 Arm Ltd. %YAML 1.2 --- $id: http://devicetree.org/schemas/i2c/i2c-controller.yaml# $schema: http://devicetree.org/meta-schemas/core.yaml# title: Common i2c-controller class maintainers: - Rob Herring properties: $nodename: pattern: "^i2c(@.+|-[a-z0-9]+)?$" i2c-bus: type: object $ref: "#" "#address-cells": const: 1 "#size-cells": const: 0 clock-frequency: minimum: 1 maximum: 5000000 i2c-scl-falling-time-ns: description: Number of nanoseconds the SCL signal takes to fall; t(f) in the I2C specification. i2c-scl-internal-delay-ns: description: Number of nanoseconds the IP core additionally needs to setup SCL. i2c-scl-rising-time-ns: description: Number of nanoseconds the SCL signal takes to rise; t(r) in the I2C specification. i2c-scl-clk-low-timeout-us: description: Number of microseconds the clock line needs to be pulled down in order to force a waiting state. i2c-transfer-timeout-us: description: Number of microseconds to wait before considering an I2C transfer has failed. i2c-scl-has-clk-low-timeout: type: boolean description: Indicates whether the controller implements the feature of wait induction through SCL low, with the timeout being implemented internally by the controller. i2c-sda-falling-time-ns: description: Number of nanoseconds the SDA signal takes to fall; t(f) in the I2C specification. i2c-analog-filter: type: boolean description: Enable analog filter for i2c lines. i2c-digital-filter: type: boolean description: Enable digital filter for i2c lines. i2c-digital-filter-width-ns: description: Width of spikes which can be filtered by digital filter (i2c-digital-filter). This width is specified in nanoseconds. i2c-analog-filter-cutoff-frequency: $ref: /schemas/types.yaml#/definitions/uint32 description: Frequency that the analog filter (i2c-analog-filter) uses to distinguish which signal to filter. Signal with higher frequency than specified will be filtered out. Only lower frequency will pass (this is applicable to a low-pass analog filter). Typical value should be above the normal i2c bus clock frequency (clock-frequency). Specified in Hz. interrupts: description: If not using interrupt-names, the first interrupt will be treated as the primary interrupt for the controller. interrupt-names: anyOf: - {} # Any name is allowed. - contains: enum: - smbus_alert description: Generic name is "smbus_alert" for the SMBusAlert signal. Other names are left to individual bindings. mctp-controller: type: boolean description: Indicates that the system is accessible via this bus as an endpoint for MCTP over I2C transport. multi-master: type: boolean description: States that there is another controller active on this bus. The OS can use this information to adapt power management to keep the arbitration awake all the time, for example. Can not be combined with 'single-master'. scl-gpios: maxItems: 1 description: Specifies the GPIO related to SCL pin. Used for GPIO bus recovery. sda-gpios: maxItems: 1 description: Specifies the GPIO related to SDA pin. Optional for GPIO bus recovery. single-master: type: boolean description: States that there is no other controller active on this bus. The OS can use this information to detect a stalled bus more reliably, for example. Can not be combined with 'multi-master'. smbalert-gpios: maxItems: 1 description: Specifies the GPIO used for the SMBALERT# line. Optional. smbus: type: boolean description: States that additional SMBus restrictions and features apply to this bus. An example of feature is SMBusHostNotify. Examples of restrictions are more reserved addresses and timeout definitions. smbus-alert: type: boolean description: states that the optional SMBus-Alert feature apply to this bus. allOf: - not: required: - i2c-scl-clk-low-timeout-us - i2c-scl-has-clk-low-timeout patternProperties: '@[0-9a-f]+$': type: object properties: reg: items: items: - oneOf: - maximum: 0x7f - minimum: 0x40000000 maximum: 0x4000007f - minimum: 0x80000000 maximum: 0x800003ff - minimum: 0xc0000000 maximum: 0xc00003ff description: | One or many I2C target addresses. These are usually 7 bit addresses. However, flags can be attached to an address. I2C_TEN_BIT_ADDRESS is used to mark a 10 bit address. It is needed to avoid the ambiguity between e.g. a 7 bit address of 0x50 and a 10 bit address of 0x050 which, in theory, can be on the same bus. Another flag is I2C_OWN_SLAVE_ADDRESS to mark addresses on which we listen to be devices ourselves. host-notify: type: boolean description: Device uses SMBus host notify protocol instead of interrupt line. Requires being connected to an adapter that supports this feature. interrupts: description: If not using interrupt-names, the first interrupt will be treated as the primary interrupt for the target. interrupt-names: anyOf: - {} # Any name is allowed. - contains: enum: - irq - wakeup description: Generic names are "irq" for the primary interrupt and "wakeup" for the wakeup interrupt. Other names are left to individual bindings. wakeup-source: description: Device can be used as a wakeup source. The device should also have "wakeup" interrupt for the device. If "wakeup" interrupt name is not present in the binding, then primary interrupt will be used as wakeup interrupt. required: - reg dependentRequired: i2c-analog-filter-cutoff-frequency: [ i2c-analog-filter ] i2c-digital-filter-width-ns: [ i2c-digital-filter ] additionalProperties: true dt-schema-2025.08/dtschema/schemas/iio/000077500000000000000000000000001504414563000175345ustar00rootroot00000000000000dt-schema-2025.08/dtschema/schemas/iio/iio-consumer.yaml000066400000000000000000000040721504414563000230340ustar00rootroot00000000000000# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) %YAML 1.2 --- $id: http://devicetree.org/schemas/iio/iio-consumer.yaml# $schema: http://devicetree.org/meta-schemas/base.yaml# title: IIO Consumer Common Properties maintainers: - Jonathan Cameron description: This binding describes generic properties a consumer of the channels provided by an IIO device may use. As well, direct readings of channels on an IIO Device, an IIO device can provide services to consumer devices. They are in the form of channel readings and properties. For example, an ADC might provide 3 channels to an analog accelerometer so that an accelerometer driver can use them to read the voltages that correspond to the accelerations on the 3 axis and apply appropriate calibration to provide useful outputs. It also describes properties of a consumer of an IIO backend device. select: true properties: io-channels: $ref: /schemas/types.yaml#/definitions/phandle-array description: > List of phandle and IIO specifier pairs, one pair for each IIO input to the device. Note: if the IIO provider specifies '0' for #io-channel-cells, then only the phandle portion of the pair will appear. io-channel-names: $ref: /schemas/types.yaml#/definitions/string-array io-backends: $ref: /schemas/types.yaml#/definitions/phandle-array description: List of phandles for IIO backends. IIO backends are devices connected to another IIO devices (consumers of the backends) providing services so that the consumer IIO device can be fully functional. One typical example of such an Hardware arrangement would be an high speed ADC that is connected to an FPGA IP core (through a serial data interface as LVDS) capable of handling the high sample rates. Examples of the provided services would be channel enablement/disablement. io-backend-names: $ref: /schemas/types.yaml#/definitions/string-array dependencies: io-channel-names: [io-channels] io-backend-names: [io-backends] additionalProperties: true dt-schema-2025.08/dtschema/schemas/iio/iio.yaml000066400000000000000000000030021504414563000211730ustar00rootroot00000000000000# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) %YAML 1.2 --- $id: http://devicetree.org/schemas/iio/iio.yaml# $schema: http://devicetree.org/meta-schemas/core.yaml# title: IIO Provider Common Properties select: true maintainers: - Jonathan Cameron description: This binding describes generic properties that can be applied to an IIO device binding. As well, direct readings of channels on an IIO Device, an IIO device can provide services in the form of readings and properties for channels to consumer devices. For example, an ADC might provide 3 channels to an analog accelerometer so that an accelerometer driver can use them to read the voltages that correspond to the accelerations on the 3 axis. properties: "#io-channel-cells": enum: [0, 1, 2] description: > Number of cells in an IIO specifier; Typically 0 for nodes with a single IIO output and 1 for nodes with multiple IIO outputs. A few unusual devices have a 2 level mapping. "#io-backend-cells": enum: [0, 1] description: Number of cells in an IIO backend; Typically 0 for nodes with a single backend and 1 for nodes with multiple backends. label: description: Unique name to identify which IIO channel or device this is. mount-matrix: $ref: /schemas/types.yaml#/definitions/non-unique-string-array minItems: 9 maxItems: 9 description: 3x3 matrix specifying the sensor orientation wrt to a reference plane. additionalProperties: true dt-schema-2025.08/dtschema/schemas/interconnects.yaml000066400000000000000000000010551504414563000225170ustar00rootroot00000000000000# SPDX-License-Identifier: BSD-2-Clause # Copyright 2021 Arm Ltd. $id: http://devicetree.org/schemas/interconnects.yaml# $schema: http://devicetree.org/meta-schemas/base.yaml# title: Interconnects Consumer Common Properties maintainers: - Rob Herring # always select the core schema select: true properties: interconnects: $ref: types.yaml#/definitions/phandle-array interconnect-names: $ref: /schemas/types.yaml#/definitions/string-array dependencies: interconnect-names: [interconnects] additionalProperties: true dt-schema-2025.08/dtschema/schemas/interrupt-controller.yaml000066400000000000000000000026361504414563000240640ustar00rootroot00000000000000# SPDX-License-Identifier: BSD-2-Clause # Copyright 2018 Linaro Ltd. # Copyright 2018 Arm Ltd. $id: http://devicetree.org/schemas/interrupt-controller.yaml# $schema: http://devicetree.org/meta-schemas/base.yaml# title: Interrupt Controller Common Properties maintainers: - Rob Herring properties: $nodename: pattern: "^interrupt-controller(@[0-9a-f,]+)*$" "#interrupt-cells": true "#address-cells": true interrupt-controller: $ref: types.yaml#/definitions/flag interrupt-map: $ref: /schemas/types.yaml#/definitions/uint32-matrix interrupt-map-mask: $ref: types.yaml#/definitions/uint32-array wakeup-parent: $ref: types.yaml#/definitions/phandle description: Some interrupt controllers in a SoC, are always powered on and have a select interrupts routed to them, so that they can wakeup the SoC from suspend. These interrupt controllers do not fall into the category of a parent interrupt controller and can be specified by the "wakeup-parent" property and contain a single phandle referring to the wakeup capable interrupt controller. dependencies: interrupt-controller: ['#interrupt-cells'] interrupt-map: ['#interrupt-cells' ] interrupt-map-mask: [ interrupt-map ] "#interrupt-cells": anyOf: - required: - interrupt-controller - required: - interrupt-map additionalProperties: true ... dt-schema-2025.08/dtschema/schemas/interrupts.yaml000066400000000000000000000014241504414563000220600ustar00rootroot00000000000000# SPDX-License-Identifier: BSD-2-Clause # Copyright 2018 Linaro Ltd. # Copyright 2018 Arm Ltd. $id: http://devicetree.org/schemas/interrupts.yaml# $schema: http://devicetree.org/meta-schemas/base.yaml# title: Interrupt Consumer Common Properties maintainers: - Rob Herring # always select the core schema select: true properties: interrupt-parent: $ref: types.yaml#/definitions/phandle interrupts: $ref: types.yaml#/definitions/uint32-matrix interrupt-names: $ref: /schemas/types.yaml#/definitions/string-array interrupts-extended: $ref: types.yaml#/definitions/phandle-array dependencies: interrupt-names: oneOf: - required: - interrupts - required: - interrupts-extended additionalProperties: true dt-schema-2025.08/dtschema/schemas/iommu/000077500000000000000000000000001504414563000201025ustar00rootroot00000000000000dt-schema-2025.08/dtschema/schemas/iommu/iommu-provider.yaml000066400000000000000000000106211504414563000237440ustar00rootroot00000000000000# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause # Copyright (c) 2014 NVIDIA CORPORATION # Copyright 2025 Arm Ltd. %YAML 1.2 --- $id: http://devicetree.org/schemas/iommu/iommu-provider.yaml# $schema: http://devicetree.org/meta-schemas/base.yaml# title: IOMMU Provider Common Properties description: > An IOMMU can provide the following services: * Remap address space to allow devices to access physical memory ranges that they otherwise wouldn't be capable of accessing. Example: 32-bit DMA to 64-bit physical addresses * Implement scatter-gather at page level granularity so that the device does not have to. * Provide system protection against "rogue" DMA by forcing all accesses to go through the IOMMU and faulting when encountering accesses to unmapped address regions. * Provide address space isolation between multiple contexts. Example: Virtualization Device nodes compatible with this binding represent hardware with some of the above capabilities. IOMMUs can be single-master or multiple-master. Single-master IOMMU devices typically have a fixed association to the master device, whereas multiple- master IOMMU devices can translate accesses from more than one master. The device tree node of the IOMMU device's parent bus must contain a valid "dma-ranges" property that describes how the physical address space of the IOMMU maps to memory. An empty "dma-ranges" property means that there is a 1:1 mapping from IOMMU to memory. maintainers: - Rob Herring # always select the core schema select: true properties: '#iommu-cells': description: > The number of cells in an IOMMU specifier needed to encode an address. The meaning of the IOMMU specifier is defined by the device tree binding of the specific IOMMU. Below are a few examples of typical use-cases: - #iommu-cells = <0>: Single master IOMMU devices are not configurable and therefore no additional information needs to be encoded in the specifier. This may also apply to multiple master IOMMU devices that do not allow the association of masters to be configured. Note that an IOMMU can by design be multi-master yet only expose a single master in a given configuration. In such cases the number of cells will usually be 1 as in the next case. - #iommu-cells = <1>: Multiple master IOMMU devices may need to be configured in order to enable translation for a given master. In such cases the single address cell corresponds to the master device's ID. In some cases more than one cell can be required to represent a single master ID. - #iommu-cells = <4>: Some IOMMU devices allow the DMA window for masters to be configured. The first cell of the address in this may contain the master device's ID for example, while the second cell could contain the start of the DMA window for the given device. The length of the DMA window is given by the third and fourth cells. Note that these are merely examples and real-world use-cases may use different definitions to represent their individual needs. Always refer to the specific IOMMU binding for the exact meaning of the cells that make up the specifier. additionalProperties: true examples: - | // Single-master IOMMU iommu1: iommu { #iommu-cells = <0>; }; master { iommus = <&iommu1>; }; - | // Multiple-master IOMMU iommu2: iommu { /* the specifier represents the ID of the master */ #iommu-cells = <1>; }; master-1 { /* device has master ID 42 in the IOMMU */ iommus = <&iommu2 42>; }; master-2 { /* device has master IDs 23 and 24 in the IOMMU */ iommus = <&iommu2 23>, <&iommu2 24>; }; - | // Multiple-master IOMMU with configurable DMA window iommu3: iommu { /* * One cell for the master ID and one cell for the * address of the DMA window. The length of the DMA * window is encoded in two cells. * * The DMA window is the range addressable by the * master (i.e. the I/O virtual address space). */ #iommu-cells = <4>; }; master { /* master ID 42, 4 GiB DMA window starting at 0 */ iommus = <&iommu3 42 0 0x1 0x0>; }; ... dt-schema-2025.08/dtschema/schemas/iommu/iommu.yaml000066400000000000000000000053161504414563000221210ustar00rootroot00000000000000# SPDX-License-Identifier: BSD-2-Clause # Copyright 2018 Linaro Ltd. %YAML 1.2 --- $id: http://devicetree.org/schemas/iommu/iommu.yaml# $schema: http://devicetree.org/meta-schemas/base.yaml# title: IOMMU Consumer Common Properties maintainers: - Rob Herring # always select the core schema select: true properties: iommus: description: > A list of phandle and IOMMU specifier pairs that describe the IOMMU master interfaces of the device. One entry in the list describes one master interface of the device. When an "iommus" property is specified in a device tree node, the IOMMU will be used for address translation. If a "dma-ranges" property exists in the device's parent node it will be ignored. An exception to this rule is if the referenced IOMMU is disabled, in which case the "dma-ranges" property of the parent shall take effect. Note that merely disabling a device tree node does not guarantee that the IOMMU is really disabled since the hardware may not have a means to turn off translation. But it is invalid in such cases to disable the IOMMU's device tree node in the first place because it would prevent any driver from properly setting up the translations. $ref: /schemas/types.yaml#/definitions/phandle-array pasid-num-bits: description: Some masters support multiple address spaces for DMA, by tagging DMA transactions with an address space identifier. By default, this is 0, which means that the device only has one address space. default: 0 dma-can-stall: type: boolean description: > When present, the master can wait for a transaction to complete for an indefinite amount of time. Upon translation fault some IOMMUs, instead of aborting the translation immediately, may first notify the driver and keep the transaction in flight. This allows the OS to inspect the fault and, for example, make physical pages resident before updating the mappings and completing the transaction. Such IOMMU accepts a limited number of simultaneous stalled transactions before having to either put back-pressure on the master, or abort new faulting transactions. Firmware has to opt-in stalling, because most buses and masters don't support it. In particular it isn't compatible with PCI, where transactions have to complete before a time limit. More generally it won't work in systems and masters that haven't been designed for stalling. For example the OS, in order to handle a stalled transaction, may attempt to retrieve pages from secondary storage in a stalled domain, leading to a deadlock. additionalProperties: true dt-schema-2025.08/dtschema/schemas/isa/000077500000000000000000000000001504414563000175305ustar00rootroot00000000000000dt-schema-2025.08/dtschema/schemas/isa/isa-bridge.yaml000066400000000000000000000015311504414563000224220ustar00rootroot00000000000000# SPDX-License-Identifier: BSD-2-Clause # Copyright 2022 Arm Ltd. %YAML 1.2 --- $id: http://devicetree.org/schemas/isa/isa-bridge.yaml# $schema: http://devicetree.org/meta-schemas/base.yaml# title: ISA Bus Bridges description: | Schema for ISA bridge nodes. This is for bridges with I/O space mapped into the parent bus. ISA Bus Binding to: IEEE Std 1275-1994 https://www.devicetree.org/open-firmware/bindings/isa/isa0_4d.ps maintainers: - Rob Herring select: properties: compatible: contains: enum: - isa - pciclass,0601 device_type: const: isa anyOf: - required: [ device_type ] - required: [ compatible ] allOf: - $ref: isa-bus.yaml# properties: compatible: enum: - isa - pciclass,0601 required: - ranges unevaluatedProperties: false dt-schema-2025.08/dtschema/schemas/isa/isa-bus.yaml000066400000000000000000000021451504414563000217610ustar00rootroot00000000000000# SPDX-License-Identifier: BSD-2-Clause # Copyright 2022 Arm Ltd. %YAML 1.2 --- $id: http://devicetree.org/schemas/isa/isa-bus.yaml# $schema: http://devicetree.org/meta-schemas/base.yaml# title: ISA Bus Nodes description: | Common properties for ISA bus nodes ISA Bus Binding to: IEEE Std 1275-1994 https://www.devicetree.org/open-firmware/bindings/isa/isa0_4d.ps maintainers: - Rob Herring properties: $nodename: pattern: "^isa@" device_type: const: isa ranges: description: Required for memory accesses or memory mapped I/O space. Optional if only indirect I/O is supported. "#address-cells": const: 2 "#size-cells": const: 1 patternProperties: '@(m|i?)[0-9a-f]{1,8}$': type: object description: Child devices properties: reg: items: items: - enum: - 0x0 # memory address - 0x1 # I/O address - description: address - description: size required: - reg required: - "#address-cells" - "#size-cells" additionalProperties: true dt-schema-2025.08/dtschema/schemas/mbox/000077500000000000000000000000001504414563000177215ustar00rootroot00000000000000dt-schema-2025.08/dtschema/schemas/mbox/mbox-consumer.yaml000066400000000000000000000012441504414563000234040ustar00rootroot00000000000000# SPDX-License-Identifier: BSD-2-Clause # Copyright 2019 ARM Ltd. # Copyright 2019 Linaro Ltd. %YAML 1.2 --- $id: http://devicetree.org/schemas/mbox/mbox-consumer.yaml# $schema: http://devicetree.org/meta-schemas/base.yaml# title: Mailbox Consumer Common Properties maintainers: - Rob Herring # always select the core schema select: true properties: mboxes: $ref: /schemas/types.yaml#/definitions/phandle-array mbox-names: $ref: /schemas/types.yaml#/definitions/string-array shmem: $ref: /schemas/types.yaml#/definitions/phandle-array items: maxItems: 1 dependencies: mbox-names: [ mboxes ] additionalProperties: true dt-schema-2025.08/dtschema/schemas/memory.yaml000066400000000000000000000026151504414563000211540ustar00rootroot00000000000000# SPDX-License-Identifier: BSD-2-Clause # Copyright 2018 Linaro Ltd. # Copyright 2018 Arm Ltd. %YAML 1.2 --- $id: http://devicetree.org/schemas/memory.yaml# $schema: http://devicetree.org/meta-schemas/core.yaml# title: /memory nodes description: | Common properties always required in /memory nodes maintainers: - Rob Herring properties: $nodename: const: '/' patternProperties: "^memory(@[0-9a-f]+)?$": type: object additionalProperties: false properties: device_type: const: memory reg: minItems: 1 maxItems: 1024 numa-node-id: $ref: types.yaml#/definitions/uint32 description: For the purpose of identification, each NUMA node is associated with a unique token known as a node id. ecc-detection-bits: default: 0 description: | If present, this indicates the number of bits of memory error which can be detected and reported by the Error-Correction Code (ECC) memory subsystem (typically 0, 1 or 2). ecc-correction-bits: default: 0 description: | If present, this indicates the number of bits of memory error which can be corrected by the Error-Correction Code (ECC) memory subsystem (typically 0, 1 or 2). required: - device_type - reg additionalProperties: true ... dt-schema-2025.08/dtschema/schemas/msi-consumer.yaml000066400000000000000000000020711504414563000222610ustar00rootroot00000000000000# SPDX-License-Identifier: BSD-2-Clause # Copyright 2022 Arm Ltd. $id: http://devicetree.org/schemas/msi-consumer.yaml# $schema: http://devicetree.org/meta-schemas/core.yaml# title: MSI consumer properties maintainers: - Rob Herring # always select the core schema select: true properties: msi-parent: description: | A list of phandle + msi-specifier pairs, one for each MSI controller which the device is capable of using. This property is unordered, and MSIs may be allocated from any combination of MSI controllers listed in the msi-parent property. If a device has restrictions on the allocation of MSIs, these restrictions must be described with additional properties. When #msi-cells is non-zero, busses with an msi-parent will require additional properties to describe the relationship between devices on the bus and the set of MSIs they can potentially generate. $ref: types.yaml#/definitions/phandle-array items: minItems: 1 maxItems: 2 additionalProperties: true dt-schema-2025.08/dtschema/schemas/numa-distance-map-v1.yaml000066400000000000000000000063631504414563000234770ustar00rootroot00000000000000# SPDX-License-Identifier: GPL-2.0 OR BSD-2-clause # Copyright 2023 Arm, Ltd. # # Based on numa.txt binding from Linux kernel # Copyright 2016 Cavium Networks, Inc. %YAML 1.2 --- $id: http://devicetree.org/schemas/numa-distance-map-v1.yaml# $schema: http://devicetree.org/meta-schemas/core.yaml# title: NUMA distance-map node maintainers: - devicetree-spec@vger.kernel.org description: | Systems employing a Non Uniform Memory Access (NUMA) architecture contain collections of hardware resources including processors, memory, and I/O buses, that comprise what is commonly known as a NUMA node. Processor accesses to memory within the local NUMA node is generally faster than processor accesses to memory outside of the local NUMA node. DT defines interfaces that allow the platform to convey NUMA node topology information to OS. The optional device tree node "distance-map" describes the relative distance (memory latency) between all numa nodes. There must be only one device node distance-map which must reside in the root node. If the distance-map node is not present, a default distance-matrix is used. properties: $nodename: const: distance-map compatible: const: numa-distance-map-v1 distance-matrix: $ref: /schemas/types.yaml#/definitions/uint32-matrix items: items: - description: 1st NUMA node ID - description: 2nd NUMA node ID - description: distance from 1st to 2nd NUMA node minimum: 10 description: | Defines a matrix to describe the relative distances between all numa nodes. It is represented as a list of node pairs and their relative distance. Note: 1. Each entry represents distance from first node to second node. The distances are equal in either direction. 2. The distance from a node to self (local distance) is represented with value 10 and all internode distance should be represented with a value greater than 10. 3. distance-matrix should have entries in lexicographical ascending order of nodes. Example: 4 nodes connected in mesh/ring topology as below, 0_______20______1 | | | | 20 20 | | | | |_______________| 3 20 2 If relative distance for each hop is 20, then internode distance would be, 0 -> 1 = 20 1 -> 2 = 20 2 -> 3 = 20 3 -> 0 = 20 0 -> 2 = 40 1 -> 3 = 40 additionalProperties: false examples: - | distance-map { compatible = "numa-distance-map-v1"; distance-matrix = <0 0 10>, <0 1 20>, <0 2 40>, <0 3 20>, <1 0 20>, <1 1 10>, <1 2 20>, <1 3 40>, <2 0 40>, <2 1 20>, <2 2 10>, <2 3 20>, <3 0 20>, <3 1 40>, <3 2 20>, <3 3 10>; }; ... dt-schema-2025.08/dtschema/schemas/opp/000077500000000000000000000000001504414563000175525ustar00rootroot00000000000000dt-schema-2025.08/dtschema/schemas/opp/opp.yaml000066400000000000000000000010671504414563000212400ustar00rootroot00000000000000# SPDX-License-Identifier: BSD-2-Clause # Copyright 2023 Linaro Ltd. %YAML 1.2 --- $id: http://devicetree.org/schemas/opp/opp.yaml# $schema: http://devicetree.org/meta-schemas/base.yaml# title: Operating Performance Points Consumer Common Properties maintainers: - Rob Herring # always select the core schema select: true properties: operating-points-v2: $ref: /schemas/types.yaml#/definitions/phandle required-opps: $ref: /schemas/types.yaml#/definitions/phandle-array minItems: 1 maxItems: 8 additionalProperties: true dt-schema-2025.08/dtschema/schemas/options.yaml000066400000000000000000000070701504414563000213370ustar00rootroot00000000000000# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-clause # Copyright 2021 Google LLC # %YAML 1.2 --- $id: http://devicetree.org/schemas/options.yaml# $schema: http://devicetree.org/meta-schemas/core.yaml# title: /options Node maintainers: - Simon Glass description: | The '/options' node does not represent a real device, but serves as a place for passing data into and between firmware components, such as memory mappings. Data in the '/options' node does not represent the hardware. It is ignored by operating systems. Properties in this node should be common to (and used by) at least two firmware projects, such as U-Boot and TF-A. Project-specific subnodes can be used for properties which are specific to a single project. This is based on the precedent set by IEEE 1275-1994 IEEE Standard for Boot (Initialization Configuration) Firmware: Core Requirements and Practices at https://www.openfirmware.info/data/docs/of1275.pdf Purpose of '/options' node -------------------------- A common problem with firmware is that many builds are needed to deal with the slight variations between different, related models of the same hardware. For example, one model may have a TPM and another may not. Devicetree provides an excellent solution to this problem, in that the devicetree to actually use on a platform can be injected in the factory based on which model is being manufactured at the time. A related problem causing build proliferation is dealing with the differences between development firmware, developer-friendly firmware (e.g. with all security features present but with the ability to access the command line), test firmware (which runs tests used in the factory), final production firmware (before signing), signed firmware (where the signatures have been inserted) and the like. Ideally all or most of these should use the same firmware build, with just some options to determine the features available. For example, being able to control whether the UART console or JTAG are available, on any image, is a great debugging aid. When the firmware consists of multiple parts (various U-Boot phases, TF-A, OP-TEE), it is helpful that all operate the same way at runtime, regardless of how they were built. This can be achieved by passing the runtime configuration (e.g. 'enable UART console', 'here are your public keys') along the chain through each firmware stage. It is frustrating to have to replicate a bug on production firmware which does not happen on developer firmware, because they are completely different builds. The '/options' node provides useful functionality for this. It allows the different controls to be 'factored out' of the firmware binaries, so they can be controlled separately from the initial source-code build. The node can be easily updated by a build or factory tool and can control various features in the firmware binaries. It is similar in concept to a Kconfig option, except that it can be changed after firmware binaries are built. The '/options' node is similar in concept to /chosen (see chosen.yaml) except that it is for passing information *into* and *between*) firmware components, instead of from firmware to the operating system. Also, while operating systems typically have a (sometimes extremely long) command line, firmware binaries typically do not support this. The devicetree provides a more structured approach in any case. properties: $nodename: const: options "#address-cells": true "#size-cells": true additionalProperties: type: object dt-schema-2025.08/dtschema/schemas/options/000077500000000000000000000000001504414563000204475ustar00rootroot00000000000000dt-schema-2025.08/dtschema/schemas/options/u-boot.yaml000066400000000000000000000120501504414563000225360ustar00rootroot00000000000000# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) # Copyright 2021 Google LLC %YAML 1.2 --- $id: http://devicetree.org/schemas/options/u-boot.yaml# $schema: http://devicetree.org/meta-schemas/core.yaml# title: U-Boot configuration node maintainers: - Simon Glass description: | The u-boot,config node provides basic configuration information to U-Boot, for use during its execution. It can be used to control U-Boot's behaviour in various ways. properties: $nodename: const: u-boot compatible: const: u-boot,config bootcmd: $ref: /schemas/types.yaml#/definitions/string description: | Allows overwriting of the boot command used by U-Boot on startup. If present, U-Boot uses this command instead. Note that this feature can work even if loading the environment is disabled, e.g. for security reasons. See also bootsecure. bootdelay-sec: description: | Allows selecting of the U-Boot bootdelay, to control whether U-Boot waits on boot or for how long. This allows this option to be configured by the build system or by a previous-stage binary. For example, if the images is being packed for testing or a user holds down a button, it may allow a delay, but disable it for production. If this property is not present, a default value is used instead. Note that this uses the 'sec' property unit, even though it allows a negative value. Values: -1: no bootdelay and the user cannot interrupt boot 0: no bootdelay but use user can still interrupt boot by holding down a key, if enabled >= 1: delay for this many seconds bootsecure: $ref: /schemas/types.yaml#/definitions/uint32 default: 0 maximum: 2 description: | Controls the execution of the boot command in U-Boot, e.g. selecting between using a special function to run commands, or the normal CLI. This can be used in production images, to restrict the amount of parsing done or the options available, to cut back on the available surface for security attacks. Values: 0: normal boot using CLI (default if not present) 1: use secure boot mechanism instead to parse and run commands other values are reserved for future use 2: use simplified command line (e.g. avoid hush) 3... reserved bootscr-address: $ref: /schemas/types.yaml#/definitions/uint64 default: 0x0 description: Holds the full address of the boot script file. It helps in making automated flow easier by fetching the 64bit address directly from DT. Value should be automatically copied to the U-Boot 'scriptaddr' variable. When it is defined, bootscr-ram-offset property should be ignored. Actually only one of them should be present in the DT. bootscr-ram-offset: $ref: /schemas/types.yaml#/definitions/uint64 default: 0x0 description: Holds the boot script file offset from the start of the ram base address. Platforms with run-time RAM-detection algorithms should use this property because it is not clear exactly where the script address should be placed. Using it will provide the option to specify boot script offset from detected RAM start. The U-Boot 'scriptaddr' variable should be composed as detected RAM start plus value of bootscr-ram-offset property. It should be used only when bootscr-address is not defined. silent-console: $ref: /schemas/types.yaml#/definitions/uint32 default: 0 maximum: 2 description: | This allows the console to be silenced by default on boot. This can allow easy disabling of console output on a production build, for example. When suppressed, the console is still active. This feature only suppresses the console output itself, on all output devices. Values: 0: console output appears as normal (default) 1: console output is suppressed but console recording still operates (if enabled) 2: console output is suppressed and not recorded boot-led: $ref: /schemas/types.yaml#/definitions/phandle description: | This is used to specify a phandle to an LED to indicate a successful boot. boot-led-period-ms: default: 250 description: | This is used to specify the default period (in ms) for an LED in blink mode. activity-led: $ref: /schemas/types.yaml#/definitions/phandle description: | This is used to specify a phandle to an LED to indicate an activity. activity-led-period-ms: default: 250 description: | This is used to specify the default period (in ms) for an LED in blink mode. required: - compatible if: required: - bootscr-address then: properties: bootscr-ram-offset: false additionalProperties: false examples: - | options { u-boot { compatible = "u-boot,config"; bootcmd = "vboot go auto"; bootdelay-sec = <(-1)>; bootsecure = <1>; bootscr-address = /bits/ 64 <0x1000>; silent-console = <1>; }; }; dt-schema-2025.08/dtschema/schemas/pci/000077500000000000000000000000001504414563000175275ustar00rootroot00000000000000dt-schema-2025.08/dtschema/schemas/pci/pci-bus-common.yaml000066400000000000000000000152601504414563000232470ustar00rootroot00000000000000# SPDX-License-Identifier: (GPL2.0-only OR BSD-2-Clause) # Copyright 2018 Linaro Ltd. # Copyright 2024 Arm Ltd. %YAML 1.2 --- $id: http://devicetree.org/schemas/pci/pci-bus-common.yaml# $schema: http://devicetree.org/meta-schemas/base.yaml# title: PCI Bus Common Properties description: | Common properties for PCI bus structure. PCI bus bridges have standardized Device Tree bindings: PCI Bus Binding to: IEEE Std 1275-1994 http://www.devicetree.org/open-firmware/bindings/pci/pci2_1.pdf And for the interrupt mapping part: Open Firmware Recommended Practice: Interrupt Mapping http://www.devicetree.org/open-firmware/practice/imap/imap0_9d.pdf maintainers: - Rob Herring properties: $nodename: pattern: "^pcie?@" ranges: oneOf: - type: boolean - minItems: 1 maxItems: 32 # Should be enough items: minItems: 5 maxItems: 8 additionalItems: true items: - enum: - 0x01000000 - 0x02000000 - 0x03000000 - 0x42000000 - 0x43000000 - 0x81000000 - 0x82000000 - 0x83000000 - 0xc2000000 - 0xc3000000 dma-ranges: oneOf: - type: boolean - minItems: 1 maxItems: 32 # Should be enough items: minItems: 5 maxItems: 8 additionalItems: true items: - enum: - 0x02000000 - 0x03000000 - 0x42000000 - 0x43000000 "#address-cells": const: 3 "#size-cells": const: 2 device_type: const: pci bus-range: $ref: /schemas/types.yaml#/definitions/uint32-array minItems: 2 maxItems: 2 items: maximum: 255 external-facing: description: When present, the port is externally facing. All bridges and endpoints downstream of this port are external to the machine. The OS can, for example, use this information to identify devices that cannot be trusted with relaxed DMA protection, as users could easily attach malicious devices to this port. type: boolean "#interrupt-cells": const: 1 interrupt-map: true # minItems: 1 # maxItems: 88 # 22 IDSEL x 4 IRQs # items: # minItems: 6 # 3 addr cells, 1 PCI IRQ cell, 1 phandle, 1+ parent addr and IRQ cells # maxItems: 16 interrupt-map-mask: items: - description: PCI high address cell minimum: 0 maximum: 0xff00 - description: PCI mid address cell const: 0 - description: PCI low address cell const: 0 - description: PCI IRQ cell minimum: 0 maximum: 7 max-link-speed: description: If present this property specifies PCI generation number for link capability. Host drivers could add this as a strategy to avoid unnecessary operation for unsupported link speed, for instance, trying to do training for unsupported link speed, etc. $ref: /schemas/types.yaml#/definitions/uint32 enum: [ 1, 2, 3, 4 ] num-lanes: description: The number of PCIe lanes $ref: /schemas/types.yaml#/definitions/uint32 enum: [ 1, 2, 4, 8, 16, 32 ] n-fts: description: The number of Fast Training Sequences (N_FTS) required by the Receiver (this component) when transitioning the Link from L0s to L0; advertised during initial Link training. Each entry in the array specifies a PCIe data rate $ref: /schemas/types.yaml#/definitions/uint8-array minItems: 1 maxItems: 5 reset-gpios: description: GPIO controlled connection to PERST# signal maxItems: 1 wake-gpios: description: GPIO controlled connection to WAKE# signal maxItems: 1 slot-power-limit-milliwatt: description: If present, specifies slot power limit in milliwatts. This property is invalid in host bridge nodes. maxItems: 1 supports-clkreq: description: If present this property specifies that CLKREQ signal routing exists from root port to downstream device and host bridge drivers can do programming which depends on CLKREQ signal existence. For example, programming root port not to advertise ASPM L1 Sub-States support if there is no CLKREQ signal. type: boolean aspm-no-l0s: description: Disables ASPM L0s capability type: boolean aspm-l0s-entry-delay-ns: description: ASPM L0s entry delay aspm-l1-entry-delay-ns: description: ASPM L1 entry delay vpcie12v-supply: description: 12v regulator phandle for the slot vpcie3v3-supply: description: 3.3v regulator phandle for the slot vpcie3v3aux-supply: description: 3.3v AUX regulator phandle for the slot eq-presets-8gts: description: Contains the equalization preset values for PCIe data rates 8.0 GT/s. Each preset value is used to adjust the transmitter settings to improve signal quality and meet the electrical requirements. These preset values go in Lane Equalization Control registers (PCIe r6.0, sec 7.7.3.4). $ref: /schemas/types.yaml#/definitions/uint16-array minItems: 1 maxItems: 16 eq-presets-16gts: description: Contains the equalization preset values for PCIe data rates 16.0 GT/s. Each preset value is used to adjust the transmitter settings to improve signal quality and meet the electrical requirements. These preset values go in Lane Equalization Control registers (PCIe r6.0, sec 7.7.5.9). $ref: /schemas/types.yaml#/definitions/uint8-array minItems: 1 maxItems: 16 eq-presets-32gts: description: Contains the equalization preset values for PCIe data rates 32.0 GT/s. Each preset value is used to adjust the transmitter settings to improve signal quality and meet the electrical requirements. These preset values go in Lane Equalization Control registers (PCIe r6.0, sec 7.7.6.9). $ref: /schemas/types.yaml#/definitions/uint8-array minItems: 1 maxItems: 16 eq-presets-64gts: description: Contains the equalization preset values for PCIe data rates 64.0 GT/s. Each preset value is used to adjust the transmitter settings to improve signal quality and meet the electrical requirements. These preset values go in Lane Equalization Control registers (PCIe r6.0, sec 7.7.7.5). $ref: /schemas/types.yaml#/definitions/uint8-array minItems: 1 maxItems: 16 patternProperties: "@1?[0-9a-f](,[0-7])?$": type: object $ref: pci-device.yaml# additionalProperties: true required: - device_type - ranges - "#address-cells" - "#size-cells" additionalProperties: true dt-schema-2025.08/dtschema/schemas/pci/pci-bus.yaml000066400000000000000000000011001504414563000217450ustar00rootroot00000000000000# SPDX-License-Identifier: (GPL2.0-only OR BSD-2-Clause) # Copyright 2018 Linaro Ltd. # Copyright 2024 Arm Ltd. %YAML 1.2 --- $id: http://devicetree.org/schemas/pci/pci-bus.yaml# $schema: http://devicetree.org/meta-schemas/base.yaml# title: PCI Host Bridge nodes description: For compatibility with existing references from host bridge bindings. New users should reference pci-host-bridge.yaml instead. maintainers: - Rob Herring $ref: pci-host-bridge.yaml# properties: # Remove when existing users fixed reg: true additionalProperties: true dt-schema-2025.08/dtschema/schemas/pci/pci-device.yaml000066400000000000000000000032701504414563000224250ustar00rootroot00000000000000# SPDX-License-Identifier: (GPL2.0-only OR BSD-2-Clause) # Copyright 2018 Linaro Ltd. # Copyright 2024 Arm Ltd. %YAML 1.2 --- $id: http://devicetree.org/schemas/pci/pci-device.yaml# $schema: http://devicetree.org/meta-schemas/base.yaml# title: PCI Device Node Common Properties description: | Common properties for PCI device nodes. Based on: PCI Bus Binding to: IEEE Std 1275-1994 http://www.devicetree.org/open-firmware/bindings/pci/pci2_1.pdf maintainers: - Rob Herring properties: compatible: contains: pattern: '^(pci[0-9a-f]{2,4},[0-9a-f]{1,4}|pciclass,[01][0-9a-f]{3}([0-9a-f]{2})?)$' reg: description: The first entry must be the configuration space. The bus number generally 0/ignored for FDT. See section 4.1.1 in PCI bus binding for further information. additionalItems: true items: - description: Configuration Space for the device items: - maximum: 0x00ffff00 # Should be 0xff00 multipleOf: 0x100 - const: 0 - const: 0 - const: 0 - const: 0 interrupts-extended: description: Occasionally PCI devices have interrupts which are not PCI interrupts. In these cases, use "interrupts-extended" so it is not ambiguous. interrupts: items: - items: - enum: [1, 2, 3, 4] # INTA, INTB, INTC, INTD assigned-addresses: $ref: /schemas/types.yaml#/definitions/uint32-array vendor-id: description: The PCI vendor ID $ref: /schemas/types.yaml#/definitions/uint32 device-id: description: The PCI device ID $ref: /schemas/types.yaml#/definitions/uint32 required: - reg additionalProperties: true dt-schema-2025.08/dtschema/schemas/pci/pci-host-bridge.yaml000066400000000000000000000061721504414563000234010ustar00rootroot00000000000000# SPDX-License-Identifier: (GPL2.0-only OR BSD-2-Clause) # Copyright 2018 Linaro Ltd. # Copyright 2024 Arm Ltd. %YAML 1.2 --- $id: http://devicetree.org/schemas/pci/pci-host-bridge.yaml# $schema: http://devicetree.org/meta-schemas/base.yaml# title: PCI Host Bridge Nodes description: | Common properties for PCI host bridge nodes. PCI host bridges implement the PCI bus binding plus additional properties for mapping host resources into PCI space. maintainers: - Rob Herring allOf: - $ref: pci-bus-common.yaml# - $ref: pci-iommu.yaml# properties: linux,pci-domain: description: If present this property assigns a fixed PCI domain number to a host bridge, otherwise an unstable (across boots) unique number will be assigned. It is required to either not set this property at all or set it for all host bridges in the system, otherwise potentially conflicting domain numbers may be assigned to root buses behind different host bridges. The domain number for each host bridge in the system must be unique. $ref: /schemas/types.yaml#/definitions/uint32 msi-map: description: > Maps a Requester ID (AKA RID) to an MSI controller and associated msi-specifier data. Each PCI device under a root complex is uniquely identified by its Requester ID. A Requester ID is a triplet of a Bus number, Device number, and Function number. For the purpose of this document, when treated as a numeric value, a RID is formatted such that: * Bits [15:8] are the Bus number. * Bits [7:3] are the Device number. * Bits [2:0] are the Function number. * Any other bits required for padding must be zero. MSIs may be distinguished in part through the use of sideband data accompanying writes. In the case of PCI devices, this sideband data may be derived from the Requester ID. A mechanism is required to associate a device with both the MSI controllers it can address, and the sideband data that will be associated with its writes to those controllers. Any RID r in the interval [rid-base, rid-base + length) is associated with the listed msi-controller, with the msi-specifier (r - rid-base + msi-base). $ref: /schemas/types.yaml#/definitions/uint32-matrix items: items: - description: The RID base matched by the entry - description: phandle to msi-controller node - description: (optional) The msi-specifier produced for the first RID matched by the entry. Currently, msi-specifier is 0 or 1 cells. - description: The length of consecutive RIDs following the RID base msi-map-mask: description: A mask to be applied to each Requester ID prior to being mapped to an msi-specifier per the msi-map property. $ref: /schemas/types.yaml#/definitions/uint32 vendor-id: description: The PCI vendor ID $ref: /schemas/types.yaml#/definitions/uint32 device-id: description: The PCI device ID $ref: /schemas/types.yaml#/definitions/uint32 dependentRequired: msi-map-mask: [ msi-map ] additionalProperties: true dt-schema-2025.08/dtschema/schemas/pci/pci-iommu.yaml000066400000000000000000000116551504414563000223220ustar00rootroot00000000000000# SPDX-License-Identifier: BSD-2-Clause # Copyright 2016,2022 Arm Ltd. %YAML 1.2 --- $id: http://devicetree.org/schemas/pci/pci-iommu.yaml# $schema: http://devicetree.org/meta-schemas/core.yaml# title: PCI IOMMU Mapping Properties description: | This document describes the generic device tree binding for describing the relationship between PCI(e) devices and IOMMU(s). Each PCI(e) device under a root complex is uniquely identified by its Requester ID (AKA RID). A Requester ID is a triplet of a Bus number, Device number, and Function number. For the purpose of this document, when treated as a numeric value, a RID is formatted such that: * Bits [15:8] are the Bus number. * Bits [7:3] are the Device number. * Bits [2:0] are the Function number. * Any other bits required for padding must be zero. IOMMUs may distinguish PCI devices through sideband data derived from the Requester ID. While a given PCI device can only master through one IOMMU, a root complex may split masters across a set of IOMMUs (e.g. with one IOMMU per bus). The generic 'iommus' property is insufficient to describe this relationship, and a mechanism is required to map from a PCI device to its IOMMU and sideband data. maintainers: - Rob Herring select: true properties: iommu-map: description: | Maps a Requester ID to an IOMMU and associated IOMMU specifier data. The property is an arbitrary number of tuples of (rid-base,iommu,iommu-base,length). Any RID r in the interval [rid-base, rid-base + length) is associated with the listed IOMMU, with the IOMMU specifier (r - rid-base + iommu-base). $ref: /schemas/types.yaml#/definitions/uint32-matrix items: items: - description: RID base maximum: 0xffff - description: phandle to IOMMU - description: IOMMU specifier base (currently always 1 cell) - description: Number of RIDs maximum: 0x10000 iommu-map-mask: description: A mask to be applied to each Requester ID prior to being mapped to an IOMMU specifier per the iommu-map property. $ref: /schemas/types.yaml#/definitions/uint32 maximum: 0xffff additionalProperties: true examples: - | / { #address-cells = <1>; #size-cells = <1>; iommu: iommu@a { reg = <0xa 0x1>; compatible = "foo,some-iommu"; #iommu-cells = <1>; }; pci: pci@f { reg = <0xf 0x1>; compatible = "foo,pcie-root-complex"; device_type = "pci"; /* * The sideband data provided to the IOMMU is the RID, * identity-mapped. */ iommu-map = <0x0 &iommu 0x0 0x10000>; }; }; - | / { #address-cells = <1>; #size-cells = <1>; iommu: iommu@a { reg = <0xa 0x1>; compatible = "foo,some-iommu"; #iommu-cells = <1>; }; pci: pci@f { reg = <0xf 0x1>; compatible = "foo,pcie-root-complex"; device_type = "pci"; /* * The sideband data provided to the IOMMU is the RID with the * function bits masked out. */ iommu-map = <0x0 &iommu 0x0 0x10000>; iommu-map-mask = <0xfff8>; }; }; - | / { #address-cells = <1>; #size-cells = <1>; iommu: iommu@a { reg = <0xa 0x1>; compatible = "foo,some-iommu"; #iommu-cells = <1>; }; pci: pci@f { reg = <0xf 0x1>; compatible = "foo,pcie-root-complex"; device_type = "pci"; /* * The sideband data provided to the IOMMU is the RID, * but the high bits of the bus number are flipped. */ iommu-map = <0x0000 &iommu 0x8000 0x8000>, <0x8000 &iommu 0x0000 0x8000>; }; }; - | / { #address-cells = <1>; #size-cells = <1>; iommu_a: iommu@a { reg = <0xa 0x1>; compatible = "foo,some-iommu"; #iommu-cells = <1>; }; iommu_b: iommu@b { reg = <0xb 0x1>; compatible = "foo,some-iommu"; #iommu-cells = <1>; }; iommu_c: iommu@c { reg = <0xc 0x1>; compatible = "foo,some-iommu"; #iommu-cells = <1>; }; pci: pci@f { reg = <0xf 0x1>; compatible = "foo,pcie-root-complex"; device_type = "pci"; /* * Devices with bus number 0-127 are mastered via IOMMU * a, with sideband data being RID[14:0]. * Devices with bus number 128-255 are mastered via * IOMMU b, with sideband data being RID[14:0]. * No devices master via IOMMU c. */ iommu-map = <0x0000 &iommu_a 0x0000 0x8000>, <0x8000 &iommu_b 0x0000 0x8000>; }; }; ... dt-schema-2025.08/dtschema/schemas/pci/pci-pci-bridge.yaml000066400000000000000000000015531504414563000231750ustar00rootroot00000000000000# SPDX-License-Identifier: (GPL2.0-only OR BSD-2-Clause) # Copyright 2018 Linaro Ltd. # Copyright 2024 Arm Ltd. %YAML 1.2 --- $id: http://devicetree.org/schemas/pci/pci-pci-bridge.yaml# $schema: http://devicetree.org/meta-schemas/base.yaml# title: PCI-PCI Bridge Nodes description: | PCI-PCI Bridge nodes are both a PCI device and a PCI bus. PCI-PCI bridges have standardized Device Tree bindings: PCI Bus Binding to: IEEE Std 1275-1994 http://www.devicetree.org/open-firmware/bindings/pci/pci2_1.pdf maintainers: - Rob Herring allOf: - $ref: pci-device.yaml# - $ref: pci-bus-common.yaml# properties: compatible: contains: const: pciclass,0604 supports-d3: description: If present, this property specifies that the bridge supports transitioning to D3 states. type: boolean additionalProperties: true dt-schema-2025.08/dtschema/schemas/phy/000077500000000000000000000000001504414563000175545ustar00rootroot00000000000000dt-schema-2025.08/dtschema/schemas/phy/phy-consumer.yaml000066400000000000000000000010701504414563000230670ustar00rootroot00000000000000# SPDX-License-Identifier: BSD-2-Clause # Copyright 2019 ARM Ltd. # Copyright 2019 Linaro Ltd. %YAML 1.2 --- $id: http://devicetree.org/schemas/phy/phy-consumer.yaml# $schema: http://devicetree.org/meta-schemas/base.yaml# title: PHY Consumer Common Properties maintainers: - Rob Herring # always select the core schema select: true properties: phys: $ref: /schemas/types.yaml#/definitions/phandle-array phy-names: $ref: /schemas/types.yaml#/definitions/string-array dependencies: phy-names: [ phys ] additionalProperties: true dt-schema-2025.08/dtschema/schemas/phy/phy-provider.yaml000066400000000000000000000015601504414563000230720ustar00rootroot00000000000000# SPDX-License-Identifier: BSD-2-Clause # Copyright 2019 Arm Ltd. $id: http://devicetree.org/schemas/phy/phy-provider.yaml# $schema: http://devicetree.org/meta-schemas/base.yaml# title: PHY Provider Common Properties maintainers: - Rob Herring # always select the core schema select: true properties: # Recommended node names: (|usb-|usb2-|usb3-|pci-|pcie-|sata-)phy "#phy-cells": true phy-supply: true phy-type: description: Some PHYs can operate in multiple modes. This sets the operating mode of the PHY. This only works for PHY providers with a single PHY as this only allows 1 mode. For instances with multiple PHYs, the mode can be set in the PHY cells. $ref: /schemas/types.yaml#/definitions/uint32 minimum: 1 maximum: 32 dependentRequired: phy-type: [ '#phy-cells' ] additionalProperties: true ... dt-schema-2025.08/dtschema/schemas/pinctrl/000077500000000000000000000000001504414563000204275ustar00rootroot00000000000000dt-schema-2025.08/dtschema/schemas/pinctrl/pinctrl-consumer.yaml000066400000000000000000000011621504414563000246170ustar00rootroot00000000000000# SPDX-License-Identifier: BSD-2-Clause # Copyright 2019 Linaro Ltd. %YAML 1.2 --- $id: http://devicetree.org/schemas/pinctrl/pinctrl-consumer.yaml# $schema: http://devicetree.org/meta-schemas/core.yaml# title: Pin Controller Consumer Common Properties maintainers: - Rob Herring # always select the core schema select: true properties: pinctrl-0: true pinctrl-names: $ref: /schemas/types.yaml#/definitions/string-array patternProperties: "^pinctrl-[0-9]+$": $ref: /schemas/types.yaml#/definitions/phandle-array dependencies: pinctrl-names: [ pinctrl-0 ] additionalProperties: true dt-schema-2025.08/dtschema/schemas/post-init-providers.yaml000066400000000000000000000106301504414563000236010ustar00rootroot00000000000000# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) # Copyright (c) 2024, Google LLC. All rights reserved. %YAML 1.2 --- $id: http://devicetree.org/schemas/post-init-providers.yaml# $schema: http://devicetree.org/meta-schemas/core.yaml# title: Post-device-initialization providers maintainers: - Saravana Kannan description: | This property is used to indicate that the device(s) pointed to by the property are not needed for the initialization of the device that lists this property. This property does not make a device (that's previously not a provider) into a provider. It simply downgrades an existing provider to a post-device-initialization provider. A device can list its providers in devicetree using one or more of the standard devicetree bindings. By default, it is assumed that the provider device can be initialized before the consumer device is initialized. However, that assumption cannot be made when there are cyclic dependencies between devices. Since each device is a provider (directly or indirectly) of the others in the cycle, there is no guaranteed safe order for initializing the devices in a cycle. We can try to initialize them in an arbitrary order and eventually successfully initialize all of them, but that doesn't always work well. For example, say, * The device tree has the following cyclic dependency X -> Y -> Z -> X (where -> denotes "depends on"). * But X is not needed to fully initialize Z (X might be needed only when a specific functionality is requested after initialization of Z). If all the other -> are mandatory initialization dependencies, then trying to initialize the devices in a loop (or arbitrarily) will always eventually end up with the devices being initialized in the order Z, Y and X. However, if Y is an optional provider for X (where X provides limited functionality when Y is not initialized and providing its services), then trying to initialize the devices in a loop (or arbitrarily) could end up with the devices being initialized in the following order: * Z, Y and X - All devices provide full functionality * Z, X and Y - X provides partial functionality * X, Z and Y - X provides partial functionality However, we always want to initialize the devices in the order Z, Y and X since that provides the full functionality without interruptions. One alternate option that might be suggested is to have the driver for X notice that Y became available at a later point and adjust the functionality it provides. However, other userspace applications could have started using X with the limited functionality before Y was available and it might not be possible to transparently transition X or the users of X to full functionality while X is in use. Similarly, when it comes to suspend (resume) ordering, it's unclear which device in a dependency cycle needs to be suspended/resumed first and trying arbitrary orders can result in system crashes or instability. Explicitly calling out which link in a cycle needs to be broken when determining the order, simplifies things a lot, improves efficiency, makes the behavior more deterministic and maximizes the functionality that can be provided without interruption. This property is used to provide this additional information between devices in a cycle by telling which provider(s) is not needed for initializing the device that lists this property. In the example above, Z would list X as a post-init-providers and the initialization dependency would become X -> Y -> Z -/-> X. So the best order to initialize them becomes clear: Z, Y and then X. select: true properties: post-init-providers: # One or more providers can be marked as post initialization provider description: List of phandles to providers that are not needed for initializing or resuming this device. $ref: /schemas/types.yaml#/definitions/phandle-array items: maxItems: 1 additionalProperties: true examples: - | gcc: clock-controller@1000 { compatible = "vendor,soc4-gcc", "vendor,soc1-gcc"; reg = <0x1000 0x80>; clocks = <&dispcc 0x1>; #clock-cells = <1>; post-init-providers = <&dispcc>; }; dispcc: clock-controller@2000 { compatible = "vendor,soc4-dispcc", "vendor,soc1-dispcc"; reg = <0x2000 0x80>; clocks = <&gcc 0xdd>; #clock-cells = <1>; }; dt-schema-2025.08/dtschema/schemas/power-domain/000077500000000000000000000000001504414563000213555ustar00rootroot00000000000000dt-schema-2025.08/dtschema/schemas/power-domain/power-domain-consumer.yaml000066400000000000000000000025741504414563000265030ustar00rootroot00000000000000# SPDX-License-Identifier: BSD-2-Clause # Copyright 2019 ARM Ltd. # Copyright 2019 Linaro Ltd. %YAML 1.2 --- $id: http://devicetree.org/schemas/power-domain/power-domain-consumer.yaml# $schema: http://devicetree.org/meta-schemas/base.yaml# title: Power Domain Consumer Common Properties maintainers: - Rob Herring # always select the core schema select: true properties: power-domains: description: A list of PM domain specifiers, as defined by bindings of the power controller that is the PM domain provider. $ref: /schemas/types.yaml#/definitions/phandle-array power-domain-names: description: A list of power domain name strings sorted in the same order as the power-domains property. Consumers drivers will use power-domain-names to match power domains with power-domains specifiers. $ref: /schemas/types.yaml#/definitions/string-array dependencies: power-domain-names: [ power-domains ] additionalProperties: true examples: - | leaky-device@12350000 { compatible = "foo,i-leak-current"; reg = <0x12350000 0x1000>; power-domains = <&power 0>; power-domain-names = "io"; }; leaky-device@12351000 { compatible = "foo,i-leak-current"; reg = <0x12351000 0x1000>; power-domains = <&power 0>, <&power 1> ; power-domain-names = "io", "clk"; }; dt-schema-2025.08/dtschema/schemas/property-units.yaml000066400000000000000000000077631504414563000227010ustar00rootroot00000000000000# SPDX-License-Identifier: BSD-2-Clause # Copyright 2018 Linaro Ltd. %YAML 1.2 --- $id: http://devicetree.org/schemas/property-units.yaml# $schema: http://devicetree.org/meta-schemas/base.yaml# title: Standard Unit Suffixes for Property names maintainers: - Devicetree Specification Mailing List description: Properties which have a unit of measure are recommended to have a unit suffix appended to the property name. The list below contains the recommended suffixes. Other variations exist in bindings, but should not be used in new bindings or added here. The inconsistency in the unit prefixes is due to selecting the most commonly used variants. It is also recommended to use the units listed here and not add additional unit prefixes. select: true # Special case(s) which don't follow the standard type. # Please don't add to this. properties: opp-hz: $ref: types.yaml#/definitions/uint64-matrix patternProperties: "-bits$": $ref: types.yaml#/definitions/uint32-array description: number of bits "-bps$": $ref: types.yaml#/definitions/uint32 description: bits per second "-kBps$": $ref: types.yaml#/definitions/uint32-array description: kilobytes per second "-percent$": $ref: types.yaml#/definitions/int32-array description: percentage "-bp$": $ref: types.yaml#/definitions/int32-array description: basis points (1/100 of a percent) "-db$": $ref: types.yaml#/definitions/int32-array description: decibels # Time/Frequency "-mhz$": $ref: types.yaml#/definitions/uint32-array description: megahertz "(^(?!opp)).*-hz$": $ref: types.yaml#/definitions/uint32-matrix description: hertz (preferred) "-sec$": $ref: types.yaml#/definitions/uint32-array description: second # Really is "marvell,wakeup-gap-ms", but look-behind requires a fixed width pattern "(? # always select the core schema select: true properties: pwms: $ref: /schemas/types.yaml#/definitions/phandle-array pwm-names: $ref: /schemas/types.yaml#/definitions/string-array dependencies: pwm-names: [ pwms ] additionalProperties: true dt-schema-2025.08/dtschema/schemas/reg.yaml000066400000000000000000000071251504414563000204220ustar00rootroot00000000000000# SPDX-License-Identifier: BSD-2-Clause # Copyright 2020 Arm Ltd. %YAML 1.2 --- $id: http://devicetree.org/schemas/reg.yaml# $schema: http://devicetree.org/meta-schemas/core.yaml# title: Address related Common Properties maintainers: - Rob Herring select: true properties: '#address-cells': maximum: 3 '#size-cells': maximum: 2 dma-ranges: oneOf: - $ref: types.yaml#/definitions/flag - $ref: types.yaml#/definitions/uint32-matrix ranges: oneOf: - $ref: types.yaml#/definitions/flag - $ref: types.yaml#/definitions/uint32-matrix reg: $ref: types.yaml#/definitions/address reg-io-width: $ref: types.yaml#/definitions/uint32 minimum: 1 maximum: 0xf description: Typically, a single set bit indicating the access size, but some uses treat this as a bit mask of allowed sizes. reg-shift: $ref: types.yaml#/definitions/uint32 enum: [ 0, 1, 2 ] nonposted-mmio: $ref: types.yaml#/definitions/flag description: If present, specifies that the device represented by this node (and its children, if any) should use non-posted memory accesses for accessing the memory described by /reg and any other inferred MMIO regions. big-endian: $ref: types.yaml#/definitions/flag description: > Force big endian register accesses unconditionally. Use this if you know the peripheral always needs to be accessed in big endian (BE) mode. If a binding supports these properties, then the binding should also specify the default behavior if none of these properties are present. In such cases, little-endian is the preferred default, but it is not a requirement. Some implementations assume that little-endian is the default, because most existing (PCI-based) drivers implicitly default to LE for their MMIO accesses. little-endian: $ref: types.yaml#/definitions/flag description: Force little endian register accesses unconditionally. Use this if you know the peripheral always needs to be accessed in little endian (LE) mode. native-endian: $ref: types.yaml#/definitions/flag description: Always use register accesses matched to the endianness of the CPU. In this case no byte swaps will ever be performed. Use this if the hardware "self-adjusts" register endianness based on the CPU's configured endianness. additionalProperties: true dependencies: "#size-cells": [ "#address-cells" ] big-endian: [ reg ] little-endian: [ reg ] native-endian: [ reg ] allOf: - if: properties: '#address-cells': const: 2 '#size-cells': const: 2 required: - '#address-cells' - '#size-cells' then: patternProperties: '@': properties: reg: items: minItems: 4 maxItems: 4 - if: properties: '#address-cells': const: 1 '#size-cells': const: 1 required: - '#address-cells' - '#size-cells' then: patternProperties: '@': properties: reg: items: minItems: 2 maxItems: 2 - if: properties: '#address-cells': const: 2 '#size-cells': const: 1 required: - '#address-cells' - '#size-cells' then: patternProperties: '@': properties: reg: items: minItems: 3 maxItems: 3 ... dt-schema-2025.08/dtschema/schemas/reserved-memory/000077500000000000000000000000001504414563000221015ustar00rootroot00000000000000dt-schema-2025.08/dtschema/schemas/reserved-memory/framebuffer.yaml000066400000000000000000000024051504414563000252520ustar00rootroot00000000000000# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) %YAML 1.2 --- $id: http://devicetree.org/schemas/reserved-memory/framebuffer.yaml# $schema: http://devicetree.org/meta-schemas/core.yaml# title: /reserved-memory framebuffer node maintainers: - devicetree-spec@vger.kernel.org allOf: - $ref: reserved-memory.yaml properties: compatible: const: framebuffer description: > This indicates a region of memory meant to be used as a framebuffer for a set of display devices. It can be used by an operating system to keep the framebuffer from being overwritten and use it as the backing memory for a display device (such as simple-framebuffer). unevaluatedProperties: false examples: - | / { compatible = "foo"; model = "foo"; #address-cells = <1>; #size-cells = <1>; chosen { framebuffer { compatible = "simple-framebuffer"; memory-region = <&fb>; }; }; reserved-memory { #address-cells = <1>; #size-cells = <1>; ranges; fb: framebuffer@80000000 { compatible = "framebuffer"; reg = <0x80000000 0x007e9000>; }; }; }; ... dt-schema-2025.08/dtschema/schemas/reserved-memory/memory-region.yaml000066400000000000000000000017351504414563000255640ustar00rootroot00000000000000# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) %YAML 1.2 --- $id: http://devicetree.org/schemas/reserved-memory/memory-region.yaml# $schema: http://devicetree.org/meta-schemas/core.yaml# title: Reserved Memory Region maintainers: - devicetree-spec@vger.kernel.org description: | Regions in the /reserved-memory node may be referenced by other device nodes by adding a memory-region property to the device node. select: true properties: memory-region: $ref: /schemas/types.yaml#/definitions/phandle-array description: > Phandle to a /reserved-memory child node assigned to the device. memory-region-names: $ref: /schemas/types.yaml#/definitions/string-array description: > A list of names, one for each corresponding entry in the memory-region property additionalProperties: true examples: - | fb0: video@12300000 { /* ... */ reg = <0x12300000 0x1000>; memory-region = <&display_reserved>; }; ... dt-schema-2025.08/dtschema/schemas/reserved-memory/reserved-memory.yaml000066400000000000000000000126241504414563000261170ustar00rootroot00000000000000# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) %YAML 1.2 --- $id: http://devicetree.org/schemas/reserved-memory/reserved-memory.yaml# $schema: http://devicetree.org/meta-schemas/core.yaml# title: /reserved-memory Child Node Common maintainers: - devicetree-spec@vger.kernel.org description: > Reserved memory is specified as a node under the /reserved-memory node. The operating system shall exclude reserved memory from normal usage one can create child nodes describing particular reserved (excluded from normal use) memory regions. Such memory regions are usually designed for the special usage by various device drivers. Each child of the reserved-memory node specifies one or more regions of reserved memory. Each child node may either use a 'reg' property to specify a specific range of reserved memory, or a 'size' property with optional constraints to request a dynamically allocated block of memory. Following the generic-names recommended practice, node names should reflect the purpose of the node (ie. "framebuffer" or "dma-pool"). Unit address (@
) should be appended to the name if the node is a static allocation. properties: reg: true size: oneOf: - $ref: /schemas/types.yaml#/definitions/uint32 - $ref: /schemas/types.yaml#/definitions/uint64 description: > Length based on parent's \#size-cells. Size in bytes of memory to reserve. alignment: oneOf: - $ref: /schemas/types.yaml#/definitions/uint32 - $ref: /schemas/types.yaml#/definitions/uint64 description: > Length based on parent's \#size-cells. Address boundary for alignment of allocation. alloc-ranges: $ref: /schemas/types.yaml#/definitions/uint32-array description: > Address and Length pairs. Specifies regions of memory that are acceptable to allocate from. iommu-addresses: $ref: /schemas/types.yaml#/definitions/phandle-array description: > A list of phandle and specifier pairs that describe static IO virtual address space mappings and carveouts associated with a given reserved memory region. The phandle in the first cell refers to the device for which the mapping or carveout is to be created. The specifier consists of an address/size pair and denotes the IO virtual address range of the region for the given device. The exact format depends on the values of the "#address-cells" and "#size-cells" properties of the device referenced via the phandle. When used in combination with a "reg" property, an IOVA mapping is to be established for this memory region. One example where this can be useful is to create an identity mapping for physical memory that the firmware has configured some hardware to access (such as a bootsplash framebuffer). If no "reg" property is specified, the "iommu-addresses" property defines carveout regions in the IOVA space for the given device. This can be useful if a certain memory region should not be mapped through the IOMMU. no-map: type: boolean description: > Indicates the operating system must not create a virtual mapping of the region as part of its standard mapping of system memory, nor permit speculative access to it under any circumstances other than under the control of the device driver using the region. reusable: type: boolean description: > The operating system can use the memory in this region with the limitation that the device driver(s) owning the region need to be able to reclaim it back. Typically that means that the operating system can use that region to store volatile or cached data that can be otherwise regenerated or migrated elsewhere. allOf: - if: required: - no-map then: not: required: - reusable - if: required: - reusable then: not: required: - no-map oneOf: - oneOf: - required: - reg - required: - size - oneOf: # IOMMU reservations - required: - iommu-addresses # IOMMU mappings - required: - reg - iommu-addresses additionalProperties: true examples: - | / { compatible = "foo"; model = "foo"; #address-cells = <2>; #size-cells = <2>; reserved-memory { #address-cells = <2>; #size-cells = <2>; ranges; adsp_resv: reservation-adsp { /* * Restrict IOVA mappings for ADSP buffers to the 512 MiB region * from 0x40000000 - 0x5fffffff. Anything outside is reserved by * the ADSP for I/O memory and private memory allocations. */ iommu-addresses = <&adsp 0x0 0x00000000 0x00 0x40000000>, <&adsp 0x0 0x60000000 0xff 0xa0000000>; }; fb: framebuffer@90000000 { reg = <0x0 0x90000000 0x0 0x00800000>; iommu-addresses = <&dc0 0x0 0x90000000 0x0 0x00800000>; }; }; bus@0 { #address-cells = <1>; #size-cells = <1>; ranges = <0x0 0x0 0x0 0x40000000>; adsp: adsp@2990000 { reg = <0x2990000 0x2000>; memory-region = <&adsp_resv>; }; dc0: display@15200000 { reg = <0x15200000 0x10000>; memory-region = <&fb>; }; }; }; ... dt-schema-2025.08/dtschema/schemas/reserved-memory/shared-dma-pool.yaml000066400000000000000000000062431504414563000257460ustar00rootroot00000000000000# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) %YAML 1.2 --- $id: http://devicetree.org/schemas/reserved-memory/shared-dma-pool.yaml# $schema: http://devicetree.org/meta-schemas/core.yaml# title: /reserved-memory DMA pool maintainers: - devicetree-spec@vger.kernel.org allOf: - $ref: reserved-memory.yaml properties: compatible: oneOf: - const: shared-dma-pool description: > This indicates a region of memory meant to be used as a shared pool of DMA buffers for a set of devices. It can be used by an operating system to instantiate the necessary pool management subsystem if necessary. - const: restricted-dma-pool description: > This indicates a region of memory meant to be used as a pool of restricted DMA buffers for a set of devices. The memory region would be the only region accessible to those devices. When using this, the no-map and reusable properties must not be set, so the operating system can create a virtual mapping that will be used for synchronization. The main purpose for restricted DMA is to mitigate the lack of DMA access control on systems without an IOMMU, which could result in the DMA accessing the system memory at unexpected times and/or unexpected addresses, possibly leading to data leakage or corruption. The feature on its own provides a basic level of protection against the DMA overwriting buffer contents at unexpected times. However, to protect against general data leakage and system memory corruption, the system needs to provide way to lock down the memory access, e.g., MPU. Note that since coherent allocation needs remapping, one must set up another device coherent pool by shared-dma-pool and use dma_alloc_from_dev_coherent instead for atomic coherent allocation. linux,cma-default: type: boolean description: > If this property is present, then Linux will use the region for the default pool of the contiguous memory allocator. linux,dma-default: type: boolean description: > If this property is present, then Linux will use the region for the default pool of the consistent DMA allocator. if: properties: compatible: contains: const: restricted-dma-pool then: properties: no-map: false reusable: false unevaluatedProperties: false examples: - | reserved-memory { #address-cells = <1>; #size-cells = <1>; ranges; /* global autoconfigured region for contiguous allocations */ linux,cma { compatible = "shared-dma-pool"; reusable; size = <0x4000000>; alignment = <0x2000>; linux,cma-default; }; display_reserved: framebuffer@78000000 { reg = <0x78000000 0x800000>; }; restricted_dma_reserved: restricted-dma-pool@50000000 { compatible = "restricted-dma-pool"; reg = <0x50000000 0x4000000>; }; }; ... dt-schema-2025.08/dtschema/schemas/reset/000077500000000000000000000000001504414563000200765ustar00rootroot00000000000000dt-schema-2025.08/dtschema/schemas/reset/reset.yaml000066400000000000000000000047641504414563000221170ustar00rootroot00000000000000# SPDX-License-Identifier: BSD-2-Clause # Copyright 2012 NVIDIA CORPORATION # Copyright 2019 Linaro Ltd. %YAML 1.2 --- $id: http://devicetree.org/schemas/reset/reset.yaml# $schema: http://devicetree.org/meta-schemas/base.yaml# title: Reset Common Properties description: > This binding is intended to represent the hardware reset signals present internally in most IC (SoC, FPGA, ...) designs. Reset signals for whole standalone chips are most likely better represented as GPIOs, although there are likely to be exceptions to this rule. Hardware blocks typically receive a reset signal. This signal is generated by a reset provider (e.g. power management or clock module) and received by a reset consumer (the module being reset, or a module managing when a sub- ordinate module is reset). This binding exists to represent the provider and consumer, and provide a way to couple the two together. A reset signal is represented by the phandle of the provider, plus a reset specifier - a list of DT cells that represents the reset signal within the provider. The length (number of cells) and semantics of the reset specifier are dictated by the binding of the reset provider, although common schemes are described below. A word on where to place reset signal consumers in device tree: It is possible in hardware for a reset signal to affect multiple logically separate HW blocks at once. In this case, it would be unwise to represent this reset signal in the DT node of each affected HW block, since if activated, an unrelated block may be reset. Instead, reset signals should be represented in the DT node where it makes most sense to control it; this may be a bus node if all children of the bus are affected by the reset signal, or an individual HW block node for dedicated reset signals. The intent of this binding is to give appropriate software access to the reset signals in order to manage the HW, rather than to slavishly enumerate the reset signal that affects each HW block. maintainers: - Rob Herring # always select the core schema select: true properties: '#reset-cells': maximum: 2 description: Number of cells in a reset specifier; Typically 0 for nodes with a single reset output and 1 for nodes with multiple reset outputs. resets: $ref: /schemas/types.yaml#/definitions/phandle-array reset-names: $ref: /schemas/types.yaml#/definitions/string-array dependencies: reset-names: [ resets ] additionalProperties: true dt-schema-2025.08/dtschema/schemas/root-node.yaml000066400000000000000000000033131504414563000215460ustar00rootroot00000000000000# SPDX-License-Identifier: BSD-2-Clause # Copyright 2018 Linaro Ltd. # Copyright 2018,2021 Arm Ltd. %YAML 1.2 --- $id: http://devicetree.org/schemas/root-node.yaml# $schema: http://devicetree.org/meta-schemas/core.yaml# title: Common root node description: | Common properties always required in the root node of the tree maintainers: - devicetree-spec@vger.kernel.org properties: $nodename: const: "/" model: { "$ref" : "types.yaml#/definitions/string-array"} chassis-type: enum: - desktop - laptop - convertible - server - all-in-one - tablet - handset - watch - embedded - television - spectacles "#address-cells": enum: [1, 2] "#size-cells": enum: [1, 2] dma-coherent: true interrupt-parent: true memory: false patternProperties: "@(0|[1-9a-f][0-9a-f]*)$": type: object additionalProperties: true properties: reg: items: minItems: 2 maxItems: 4 minItems: 1 maxItems: 1024 ranges: oneOf: - items: minItems: 3 maxItems: 7 minItems: 1 maxItems: 1024 - $ref: types.yaml#/definitions/flag anyOf: - required: - reg - required: - ranges required: - compatible - model - "#address-cells" - "#size-cells" additionalProperties: true examples: - | / { compatible = "acme,boogieboard"; model = "Acme Ltd. Boogieboard developer system"; chassis-type = "embedded"; #address-cells = <1>; #size-cells = <1>; memory@0 { reg = <0 0x10000000>; }; $path = "/"; } dt-schema-2025.08/dtschema/schemas/serial.yaml000066400000000000000000000005561504414563000211250ustar00rootroot00000000000000# SPDX-License-Identifier: BSD-2-Clause # Copyright 2019 Linaro Ltd. %YAML 1.2 --- $id: http://devicetree.org/schemas/serial.yaml# $schema: http://devicetree.org/meta-schemas/core.yaml# title: Serial Device Common Properties maintainers: - Rob Herring properties: $nodename: pattern: "^serial(@[0-9a-f,]+)*$" additionalProperties: true dt-schema-2025.08/dtschema/schemas/simple-bus.yaml000066400000000000000000000034101504414563000217160ustar00rootroot00000000000000# SPDX-License-Identifier: BSD-2-Clause # Copyright 2018 Linaro Ltd. # Copyright 2021 Arm Ltd. %YAML 1.2 --- $id: http://devicetree.org/schemas/simple-bus.yaml# $schema: http://devicetree.org/meta-schemas/core.yaml# title: simple-bus nodes description: Common simple-bus binding maintainers: - Rob Herring properties: $nodename: pattern: "^([a-z][a-z0-9\\-]+-bus|bus|localbus|soc|axi|ahb|apb)(@.+)?$" compatible: contains: const: simple-bus ranges: true dma-ranges: true "#address-cells": enum: [ 1, 2 ] "#size-cells": enum: [ 1, 2 ] nonposted-mmio: $ref: /schemas/types.yaml#/definitions/flag description: If present, specifies that direct children of this bus should use non-posted memory accesses (i.e. a non-posted mapping mode) for MMIO ranges. patternProperties: # All other properties should be child nodes with unit-address and 'reg' "@(0|[1-9a-f][0-9a-f]*)$": type: object additionalProperties: true properties: reg: items: minItems: 2 maxItems: 4 minItems: 1 maxItems: 1024 ranges: oneOf: - items: minItems: 3 maxItems: 7 minItems: 1 maxItems: 1024 - $ref: types.yaml#/definitions/flag anyOf: - required: - reg - required: - ranges additionalProperties: description: Anything else must be a property or have empty 'ranges'. An empty 'ranges' is only appropriate if the child node is another 'simple-bus' or similar. if: type: object then: properties: ranges: type: boolean required: - ranges required: - compatible - "#address-cells" - "#size-cells" - ranges dt-schema-2025.08/dtschema/schemas/system-idle-states.yaml000066400000000000000000000034161504414563000234040ustar00rootroot00000000000000# SPDX-License-Identifier: BSD-2-Clause # Copyright 2025 BayLibre %YAML 1.2 --- $id: http://devicetree.org/schemas/system-idle-states.yaml# $schema: http://devicetree.org/meta-schemas/core.yaml# title: System Idle States maintainers: - Markus Schneider-Pargmann description: A system idle state node represents a system state that can have certain limitations and power properties. properties: $nodename: const: system-idle-states patternProperties: "^system-[a-z0-9-]+$": type: object additionalProperties: false description: The node represents a system state description. properties: compatible: const: system-idle-state idle-state-name: $ref: /schemas/types.yaml#/definitions/string description: | Name of the system state. These are the available states: - standby: Light suspend, peripherals may remain active - mem-mcu-active: DDR in self-refresh, MCU/coprocessor running, main cores off - mem: DDR in self-refresh, all cores off - mem-deep: DDR in self-refresh, all other hardware off except some wake logic - off-wake: System powered off, wake-up logic remains active - off: Complete power off, lowest possible power state enum: - standby - mem-mcu-active - mem - mem-deep - off-wake - off required: - compatible - idle-state-name additionalProperties: false examples: - | system-idle-states { system-suspend { compatible = "system-idle-state"; idle-state-name = "mem"; }; system-off { compatible = "system-idle-state"; idle-state-name = "off"; }; }; dt-schema-2025.08/dtschema/schemas/thermal/000077500000000000000000000000001504414563000204105ustar00rootroot00000000000000dt-schema-2025.08/dtschema/schemas/thermal/thermal.yaml000066400000000000000000000017421504414563000227340ustar00rootroot00000000000000# SPDX-License-Identifier: BSD-2-Clause # Copyright 2023 Collabora Ltd. %YAML 1.2 --- $id: http://devicetree.org/schemas/thermal/thermal.yaml# $schema: http://devicetree.org/meta-schemas/base.yaml# title: Thermal Consumer Common Properties maintainers: - Rob Herring # always select the core schema select: true properties: thermal-zones: anyOf: - type: object # for nodes named 'thermal-zones' - $ref: /schemas/types.yaml#/definitions/phandle-array description: List of thermal zone phandles, one for each thermal zone input to the device. thermal-zone-names: $ref: /schemas/types.yaml#/definitions/string-array description: List of thermal zone name strings sorted in the same order as the thermal-zones property. Consumer drivers will use thermal-zone-names to match thermal zone input names with thermal zone specifiers. dependentRequired: thermal-zone-names: [ thermal-zones ] additionalProperties: true dt-schema-2025.08/dtschema/schemas/trigger/000077500000000000000000000000001504414563000204175ustar00rootroot00000000000000dt-schema-2025.08/dtschema/schemas/trigger/trigger-source.yaml000066400000000000000000000021361504414563000242460ustar00rootroot00000000000000# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) %YAML 1.2 --- $id: http://devicetree.org/schemas/trigger/trigger-source.yaml# $schema: http://devicetree.org/meta-schemas/core.yaml# title: Trigger source provider maintainers: - David Lechner description: A trigger source providers are an abstraction for anything that provides a signal to trigger an event. For example, this could be a disk activity signal that triggers a LED to turn on or off or it could be a data ready signal that triggers a SPI offload to read data without a software interrupt. Each trigger source provider should be represented by a device tree node. select: true properties: '#trigger-source-cells': description: Number of cells required to specify a trigger source. This property is is applied to the trigger source provider. trigger-sources: $ref: /schemas/types.yaml#/definitions/phandle-array description: This property is applied to the trigger source consumer to describe the connection to a trigger source provider. additionalProperties: true dt-schema-2025.08/dtschema/schemas/types.yaml000066400000000000000000000067131504414563000210130ustar00rootroot00000000000000# SPDX-License-Identifier: BSD-2-Clause # Copyright 2018 Linaro Ltd. $id: http://devicetree.org/schemas/types.yaml# $schema: http://devicetree.org/meta-schemas/base.yaml# title: Core devicetree property data types description: Schema for core devicetree data types. Binding schema can reference these types. maintainers: - Rob Herring select: true definitions: flag: oneOf: - type: boolean const: true - type: 'null' non-unique-string-array: type: array items: { type: string } minItems: 1 string-array: allOf: - $ref: "#/definitions/non-unique-string-array" - uniqueItems: true string: allOf: - $ref: "#/definitions/string-array" - maxItems: 1 uint8: type: integer typeSize: 8 minimum: 0 maximum: 0xff uint8-array: type: array minItems: 1 items: $ref: "#/definitions/uint8" uint8-matrix: type: array minItems: 1 items: $ref: "#/definitions/uint8-array" int8: type: integer typeSize: 8 minimum: -128 maximum: 127 int8-array: type: array minItems: 1 items: $ref: "#/definitions/int8" int8-matrix: type: array minItems: 1 items: $ref: "#/definitions/int8-array" uint16: type: integer typeSize: 16 minimum: 0 maximum: 0xffff uint16-array: type: array minItems: 1 items: $ref: "#/definitions/uint16" uint16-matrix: type: array minItems: 1 items: $ref: "#/definitions/uint16-array" int16: type: integer typeSize: 16 minimum: -8192 maximum: 8191 int16-array: type: array minItems: 1 items: $ref: "#/definitions/int16" int16-matrix: type: array minItems: 1 items: $ref: "#/definitions/int16-array" uint32: type: integer typeSize: 32 minimum: 0 maximum: 0xffffffff uint32-array: type: array minItems: 1 items: $ref: "#/definitions/uint32" uint32-matrix: type: array minItems: 1 items: $ref: "#/definitions/uint32-array" int32: type: integer minimum: -2147483648 maximum: 2147483647 int32-array: type: array minItems: 1 items: $ref: "#/definitions/int32" int32-matrix: type: array minItems: 1 items: $ref: "#/definitions/int32-array" int64: type: integer typeSize: 64 minimum: -9223372036854775808 maximum: 9223372036854775807 int64-array: type: array minItems: 1 items: $ref: "#/definitions/int64" int64-matrix: type: array minItems: 1 items: $ref: "#/definitions/int64-array" uint64: type: integer typeSize: 64 minimum: 0 maximum: 0xffffffffffffffff uint64-array: type: array minItems: 1 items: $ref: "#/definitions/uint64" uint64-matrix: type: array minItems: 1 items: $ref: "#/definitions/uint64-array" phandle: $ref: "#/definitions/phandle-array" maxItems: 1 items: maxItems: 1 phandle-array: type: array minItems: 1 items: type: array minItems: 1 items: - oneOf: - type: integer minimum: 1 maximum: 0xffffffff - type: integer const: 0 additionalItems: $ref: "#/definitions/uint32" address: $ref: "#/definitions/uint32-matrix" items: minItems: 1 maxItems: 5 # At most 3 address cells and 2 size cells dt-schema-2025.08/dtschema/schemas/wakeup-source.yaml000066400000000000000000000050571504414563000224410ustar00rootroot00000000000000# SPDX-License-Identifier: BSD-2-Clause # Copyright 2015,2024 Arm Ltd. %YAML 1.2 --- $id: http://devicetree.org/schemas/wakeup-source.yaml# $schema: http://devicetree.org/meta-schemas/core.yaml# title: Wakeup sources description: > Nodes that describe devices which have wakeup capability may contain a "wakeup-source" property. This property can be either boolean or a phandle array containing references to system idle states in which this device has a wakeup capability. If the device is marked as a wakeup-source, interrupt wake capability depends on the device specific "interrupt-names" property. If no interrupts are labeled as wake capable, then it is up to the device to determine which interrupts can wake the system. However if a device has a dedicated interrupt as the wakeup source, then it needs to specify/identify it using a device specific interrupt name. In such cases only that interrupt can be used as a wakeup interrupt. While various legacy interrupt names exist, new devices should use "wakeup" as the canonical interrupt name. maintainers: - Rob Herring select: true properties: wakeup-source: oneOf: - type: boolean - $ref: /schemas/types.yaml#/definitions/phandle-array items: maxItems: 1 description: List of phandles to system idle state nodes. The device can be a wakeup source in the given system states. additionalProperties: true examples: - | # With "wakeup" interrupt name device@10000 { compatible = "vendor,device-id"; reg = <0x10000 0x1000>; interrupts = <0 19 4>, <0 21 4>, <0 22 4>; interrupt-names = "ack", "err", "wakeup"; wakeup-source; }; - | # Without "wakeup" interrupt name embedded-controller@1e { compatible = "google,cros-ec-i2c"; reg = <0x1e>; interrupts = <6 0>; wakeup-source; }; - | # Without interrupts keys { compatible = "gpio-keys"; #address-cells = <1>; #size-cells = <0>; button { debounce-interval = <50>; wakeup-source; linux,code = <116>; label = "POWER"; gpios = <&iofpga_gpio0 0 0x4>; }; }; - | # With power states specified mcu_mcan0: can@4e08000 { compatible = "bosch,m_can"; reg = <0x00 0x4e08000 0x00 0x200>, <0x00 0x4e00000 0x00 0x8000>; reg-names = "m_can", "message_ram"; wakeup-source = <&system_partial_io>, <&system_deep_sleep>; }; ... dt-schema-2025.08/dtschema/validator.py000066400000000000000000000513611504414563000176760ustar00rootroot00000000000000# SPDX-License-Identifier: BSD-2-Clause # Copyright 2018 Linaro Ltd. # Copyright 2018-2023 Arm Ltd. import os import sys import re import copy import glob import json import jsonschema from jsonschema.exceptions import RefResolutionError import dtschema from dtschema.lib import _is_string_schema from dtschema.lib import _get_array_range from dtschema.schema import DTSchema schema_basedir = os.path.dirname(os.path.abspath(__file__)) def _merge_dim(dim1, dim2): d = [] for i in range(0, 2): minimum = min(dim1[i][0], dim2[i][0]) maximum = max(dim1[i][1], dim2[i][1]) if maximum == 1: minimum = 1 d.insert(i, (minimum, maximum)) return tuple(d) type_re = re.compile('(address|flag|u?int(8|16|32|64)(-(array|matrix))?|string(-array)?|phandle(-array)?)') def _extract_prop_type(props, schema, propname, subschema, is_pattern): if propname.startswith('$'): return if not isinstance(subschema, dict): if subschema is True: default_type = {'type': None, '$id': [schema['$id']]} if is_pattern: default_type['regex'] = re.compile(propname) props.setdefault(propname, [default_type]) return new_prop = {} prop_type = None # We only support local refs if '$ref' in subschema: if subschema['$ref'].startswith('#/'): if propname in props: for p in props[propname]: if schema['$id'] in p['$id']: return sch_path = subschema['$ref'].split('/')[1:] tmp_subschema = schema for p in sch_path: tmp_subschema = tmp_subschema[p] #print(propname, sch_path, tmp_subschema, file=sys.stderr) _extract_prop_type(props, schema, propname, tmp_subschema, is_pattern) elif '/properties/' in subschema['$ref']: prop_type = subschema['$ref'].split('/')[-1] if prop_type == propname: prop_type = None for k in subschema.keys() & {'allOf', 'oneOf', 'anyOf'}: for v in subschema[k]: _extract_prop_type(props, schema, propname, v, is_pattern) props.setdefault(propname, []) if ('type' in subschema and subschema['type'] == 'object') or \ subschema.keys() & {'properties', 'patternProperties', 'additionalProperties'}: prop_type = 'node' else: try: prop_type = type_re.search(subschema['$ref']).group(0) except: if 'type' in subschema and subschema['type'] == 'boolean': prop_type = 'flag' elif 'items' in subschema: items = subschema['items'] if (isinstance(items, list) and _is_string_schema(items[0])) or \ (isinstance(items, dict) and _is_string_schema(items)): # implicit string type prop_type = 'string-array' elif not (isinstance(items, list) and len(items) == 1 and 'items' in items and isinstance(items['items'], list) and len(items['items']) == 1): # Keep in sync with property-units.yaml if re.search('-microvolt$', propname): prop_type = 'int32-matrix' elif re.search('(^(?!opp)).*-hz$', propname): prop_type = 'uint32-matrix' else: prop_type = None else: prop_type = None elif '$ref' in subschema and re.search(r'\.yaml#?$', subschema['$ref']): prop_type = 'node' new_prop['type'] = prop_type new_prop['$id'] = [schema['$id']] if is_pattern: new_prop['regex'] = re.compile(propname) if not prop_type: if len(props[propname]) == 0: props[propname] += [new_prop] return # handle matrix dimensions if prop_type == 'phandle-array' or prop_type.endswith('-matrix'): outer = _get_array_range(subschema) if 'items' in subschema: if isinstance(subschema['items'], list): inner = _get_array_range(subschema['items'][0]) else: inner = _get_array_range(subschema.get('items', {})) else: inner = (0, 0) dim = (outer, inner) new_prop['dim'] = dim else: dim = None dup_prop = None for p in props[propname]: if p['type'] is None: dup_prop = p break if dim and \ (p['type'] == 'phandle-array' or p['type'].endswith('-matrix')): p['dim'] = _merge_dim(p['dim'], dim) if schema['$id'] not in p['$id']: p['$id'] += [schema['$id']] new_prop = None break if p['type'] == prop_type: new_prop = None if schema['$id'] not in p['$id']: p['$id'] += [schema['$id']] break if 'string' in prop_type and 'string' in p['type']: # Extend string to string-array if prop_type == 'string-array': p['type'] = prop_type if schema['$id'] not in p['$id']: p['$id'] += [schema['$id']] new_prop = None break if dup_prop: props[propname].remove(dup_prop) if new_prop: props[propname] += [new_prop] if subschema.keys() & {'properties', 'patternProperties', 'additionalProperties'}: _extract_subschema_types(props, schema, subschema) def _extract_subschema_types(props, schema, subschema): if not isinstance(subschema, dict): return if 'additionalProperties' in subschema: _extract_subschema_types(props, schema, subschema['additionalProperties']) for k in subschema.keys() & {'allOf', 'oneOf', 'anyOf'}: for v in subschema[k]: _extract_subschema_types(props, schema, v) for k in subschema.keys() & {'properties', 'patternProperties'}: if isinstance(subschema[k], dict): for p, v in subschema[k].items(): _extract_prop_type(props, schema, p, v, k == 'patternProperties') def extract_types(schemas): props = {} for sch in schemas.values(): _extract_subschema_types(props, sch, sch) for prop in props.values(): for v in prop: if not v['type'] or v['type'] == 'node': continue prop_type = v['type'] if not type_re.search(prop_type): v['type'] = props[prop_type][0]['type'] break return props def get_prop_types(schemas): pat_props = {} props = extract_types(schemas) # hack to remove aliases and generic patterns try: del props[r'^[a-z][a-z0-9\-]*$'] except: pass # Remove all node types for val in props.values(): val[:] = [t for t in val if t['type'] != 'node'] for key in [key for key in props if len(props[key]) == 0]: del props[key] # Split out pattern properties for key in [key for key in props if 'regex' in props[key][0]]: # Only want patternProperties with type and some amount of fixed string if props[key][0]['type'] is not None: pat_props[key] = props[key] del props[key] # Delete any entries without a type, but matching a patternProperty for key in [key for key in props if props[key][0]['type'] is None]: for pat, val in pat_props.items(): if val[0]['type'] and val[0]['regex'].search(key): del props[key] break return [props, pat_props] def make_compatible_schema(schemas): compat_sch = [{'enum': []}] compatible_list = set() for sch in schemas.values(): compatible_list |= dtschema.extract_compatibles(sch) # Allow 'foo' values for examples compat_sch += [{'pattern': '^foo'}] # Allow 'test,' vendor prefix for test cases compat_sch += [{'pattern': '^test,'}] prog = re.compile(r'.*[\^\[{\(\$].*') for c in compatible_list: if prog.match(c): # Exclude the generic pattern if c != r'^[a-zA-Z0-9][a-zA-Z0-9,+\-._/]+$' and \ not re.search(r'\.[+*]', c) and \ c.startswith('^') and c.endswith('$'): compat_sch += [{'pattern': c}] else: compat_sch[0]['enum'].append(c) compat_sch[0]['enum'].sort() schemas['generated-compatibles'] = { '$id': 'generated-compatibles', '$filename': 'Generated schema of documented compatible strings', 'select': True, 'properties': { 'compatible': { 'items': { 'anyOf': compat_sch } } } } def process_schema(filename): try: dtsch = DTSchema(filename) except: print(f"{filename}: ignoring, error parsing file", file=sys.stderr) return # Check that the validation schema is valid try: dtsch.is_valid() except jsonschema.SchemaError as exc: print(f"{filename}: ignoring, error in schema: " + ': '.join(str(x) for x in exc.path), file=sys.stderr) #print(exc.message) return schema = dtsch.fixup() schema["type"] = "object" schema["$filename"] = filename return schema def _add_schema(schemas, filename): sch = process_schema(os.path.abspath(filename)) if not sch or '$id' not in sch: return False if sch['$id'] in schemas: print(f"{sch['$filename']}: warning: ignoring duplicate '$id' value '{sch['$id']}'", file=sys.stderr) return False else: schemas[sch['$id']] = sch return True def process_schemas(schema_paths, core_schema=True): schemas = {} for filename in schema_paths: if not os.path.isfile(filename): continue _add_schema(schemas, filename) if core_schema: schema_paths.append(os.path.join(schema_basedir, 'schemas/')) for path in schema_paths: count = 0 if not os.path.isdir(path): continue for filename in glob.iglob(os.path.join(os.path.abspath(path), "**/*.yaml"), recursive=True): if _add_schema(schemas, filename): count += 1 if count == 0: print(f"warning: no schema found in path: {path}", file=sys.stderr) return schemas def typeSize(validator, typeSize, instance, schema): try: size = instance.size except: size = 32 if typeSize != size: yield jsonschema.ValidationError("size is %r, expected %r" % (size, typeSize)) class DTValidator: '''Custom Validator for Devicetree Schemas Overrides the Draft7 metaschema with the devicetree metaschema. This validator is used in exactly the same way as the Draft7Validator. Schema files can be validated with the .check_schema() method, and .validate() will check the data in a devicetree file. ''' DtValidator = jsonschema.validators.extend(jsonschema.Draft201909Validator, {'typeSize': typeSize}) def __init__(self, schema_files, filter=None): self.schemas = {} self.resolver = jsonschema.RefResolver('', None, handlers={'http': self.http_handler}) schema_cache = None if len(schema_files) == 1 and os.path.isfile(schema_files[0]): # a processed schema file with open(schema_files[0], 'r', encoding='utf-8') as f: try: schema_cache = json.load(f) except json.decoder.JSONDecodeError: try: f.seek(0) import ruamel.yaml yaml = ruamel.yaml.YAML(typ='safe') schema_cache = yaml.load(f.read()) except: print("preprocessed schema file is not valid JSON or YAML\n", file=sys.stderr) raise # Ensure the cache is a processed schema and not just a single schema file if '$id' in schema_cache: schema_cache = None elif schema_cache.pop('version', None) != dtschema.__version__: raise Exception(f"Processed schema out of date, delete and retry: {os.path.abspath(schema_files[0])}") if schema_cache: if 'generated-types' in schema_cache: self.props = schema_cache['generated-types']['properties'] if 'generated-pattern-types' in schema_cache: self.pat_props = copy.deepcopy(schema_cache['generated-pattern-types']['properties']) for k in self.pat_props: self.pat_props[k][0]['regex'] = re.compile(k) self.schemas = schema_cache else: self.schemas = process_schemas(schema_files) self.make_property_type_cache() make_compatible_schema(self.schemas) for k in self.pat_props: self.pat_props[k][0]['regex'] = re.compile(k) # Speed up iterating thru schemas in validation by saving a list of schemas # to always apply and a map of compatible strings to schema. self.always_schemas = [] self.compat_map = {} for sch in self.schemas.values(): if 'select' in sch: if sch['select'] is not False: self.always_schemas += [sch['$id']] elif 'properties' in sch and 'compatible' in sch['properties']: compatibles = dtschema.extract_node_compatibles(sch['properties']['compatible']) if len(compatibles) > 1: compatibles = set(compatibles) - {'syscon', 'simple-mfd', 'simple-bus'} for c in compatibles: if not schema_cache and c in self.compat_map: print(f'Warning: Duplicate compatible "{c}" found in schemas matching "$id":\n' f'\t{self.compat_map[c]}\n\t{sch["$id"]}', file=sys.stderr) self.compat_map[c] = sch['$id'] self.schemas['version'] = dtschema.__version__ def http_handler(self, uri): '''Custom handler for http://devicetree.org references''' try: uri += '#' if uri in self.schemas: return self.schemas[uri] else: # If we have a schema_cache, then the schema should have been there unless the schema had errors if len(self.schemas): return {'not': {'description': f"Can't find referenced schema: {uri}"}} except: raise RefResolutionError('Error in referenced schema matching $id: ' + uri) def annotate_error(self, id, error): error.schema_file = id error.linecol = -1, -1 error.note = None def _filter_match(self, schema_id, filter): if not filter: return True for f in filter: if f in schema_id: return True return False def iter_errors(self, instance, filter=None, compatible_match=False): if 'compatible' in instance: for inst_compat in instance['compatible']: if inst_compat in self.compat_map: schema_id = self.compat_map[inst_compat] if self._filter_match(schema_id, filter): schema = self.schemas[schema_id] for error in self.DtValidator(schema, resolver=self.resolver, ).iter_errors(instance): self.annotate_error(schema['$id'], error) yield error break if compatible_match: return for schema_id in self.always_schemas: if not self._filter_match(schema_id, filter): continue schema = {'if': self.schemas[schema_id]['select'], 'then': self.schemas[schema_id]} for error in self.DtValidator(schema, resolver=self.resolver, ).iter_errors(instance): self.annotate_error(schema_id, error) yield error def validate(self, instance, filter=None): for error in self.iter_errors(instance, filter=filter): raise error def get_undocumented_compatibles(self, compatible_list): undoc_compats = [] validator = self.DtValidator(self.schemas['generated-compatibles']) for compat in compatible_list: if not validator.is_valid({"compatible": [compat]}): undoc_compats += [compat] return undoc_compats def check_missing_property_types(self): for p, val in self.props.items(): if val[0]['type'] is None: for id in val[0]['$id']: print(f"{self.schemas[id]['$filename']}: {p}: missing type definition", file=sys.stderr) def check_duplicate_property_types(self): """ Check for properties with multiple types consisting of a mixture of integer scalar, array or matrix. These cannot be decoded reliably. """ for p, val in self.props.items(): # Exclude some known problematic properties if p in ['dma-masters']: continue has_int = 0 has_array = 0 has_matrix = 0 for v in val: if v['type'] is None: break if re.match(r'u?int(8|16|32|64)$', v['type']): has_int += 1 elif re.match(r'u?int.+-array', v['type']): has_array += 1 elif re.match(r'u?int.+-matrix', v['type']): has_matrix += 1 min_size = v['dim'][0][0] * v['dim'][1][0] elif v['type'] == 'phandle-array': has_matrix += 1 min_size = v['dim'][0][0] * v['dim'][1][0] if not ((has_int and (has_array or (has_matrix and min_size == 1))) or (has_array and has_matrix)): continue for v in val: for sch_id in v['$id']: print(f"{self.schemas[sch_id]['$filename']}: {p}: multiple incompatible types: {v['type']}", file=sys.stderr) def make_property_type_cache(self): self.props, self.pat_props = get_prop_types(self.schemas) self.check_missing_property_types() self.check_duplicate_property_types() for val in self.props.values(): for t in val: del t['$id'] self.schemas['generated-types'] = { '$id': 'generated-types', '$filename': 'Generated property types', 'select': False, 'properties': {k: self.props[k] for k in sorted(self.props)} } pat_props = copy.deepcopy(self.pat_props) for val in pat_props.values(): for t in val: t.pop('regex', None) del t['$id'] self.schemas['generated-pattern-types'] = { '$id': 'generated-pattern-types', '$filename': 'Generated pattern property types', 'select': False, 'properties': {k: pat_props[k] for k in sorted(pat_props)} } def property_get_all(self): all_props = copy.deepcopy({**self.props, **self.pat_props}) for p, v in all_props.items(): v[0].pop('regex', None) return all_props def property_get_type(self, propname): ptype = set() if propname in self.props: for v in self.props[propname]: if v['type']: ptype.add(v['type']) if len(ptype) == 0: for v in self.pat_props.values(): if v[0]['type'] and v[0]['type'] not in ptype and v[0]['regex'].search(propname): ptype.add(v[0]['type']) # Don't return 'node' as a type if there's other types if len(ptype) > 1 and 'node' in ptype: ptype -= {'node'} return ptype def property_get_type_dim(self, propname): if propname in self.props: for v in self.props[propname]: if 'dim' in v: return v['dim'] for v in self.pat_props.values(): if v[0]['type'] and 'dim' in v[0] and v[0]['regex'].search(propname): return v[0]['dim'] return None def property_has_fixed_dimensions(self, propname): dim = self.property_get_type_dim(propname) if dim and ((dim[0][0] > 0 and dim[0][0] == dim[0][1]) or \ (dim[1][0] > 0 and dim[1][0] == dim[1][1])): return True return False def decode_dtb(self, dtb): return [dtschema.dtb.fdt_unflatten(self, dtb)] dt-schema-2025.08/example-schema.yaml000066400000000000000000000105661504414563000173260ustar00rootroot00000000000000# SPDX-License-Identifier: BSD-2-Clause # Copyright 2018 Linaro Ltd. %YAML 1.2 --- # All the top-level keys are standard json-schema keywords except for # 'maintainers' and 'select' # $id is a unique idenifier based on the filename $id: http://devicetree.org/schemas/example-schema.yaml# $schema: http://devicetree.org/meta-schemas/core.yaml# title: An example schema annotated with jsonschema details maintainers: - Rob Herring description: | A more detailed multi-line description of the binding. Details about the hardware device and any links to datasheets can go here. The end of the description is marked by indentation less than the first line in the description. select: false # 'select' is a schema applied to a DT node to determine if this binding # schema should be applied to the node. It is optional and by default the # possible compatible strings are extracted and used to match. properties: # A dictionary of DT properties for this binding schema compatible: # More complicated schema can use oneOf (XOR), anyOf (OR), or allOf (AND) # to handle different conditions. # In this case, it's needed to handle a variable number of values as there # isn't another way to express a constraint of the last string value. # The boolean schema must be a list of schemas. oneOf: - items: # items is a list of possible values for the property. The number of # values is determined by the number of elements in the list. # Order in lists is significant, order in dicts is not # Must be one of the 1st enums followed by the 2nd enum # # Each element in items should be 'enum' or 'const' - enum: - vendor,soc4-ip - vendor,soc3-ip - vendor,soc2-ip - enum: - vendor,soc1-ip # additionalItems being false is implied # minItems/maxItems equal to 2 is implied - items: # 'const' is just a special case of an enum with a single possible value - const: vendor,soc1-ip reg: # The description of each element defines the order and implicitly defines # the number of reg entries items: - description: core registers - description: aux registers # minItems/maxItems equal to 2 is implied reg-names: # The core schema enforces this is a string array items: - const: core - const: aux clocks: # Only a single entry, so just need to set the max number of items. maxItems: 1 clock-names: items: - const: bus interrupts: # Either 1 or 2 interrupts can be present minItems: 1 maxItems: 2 items: - description: tx or combined interrupt - description: rx interrupt description: | A variable number of interrupts warrants a description of what conditions affect the number of interrupts. Otherwise, descriptions on standard properties are not necessary. interrupt-names: # minItems must be specified here because the default would be 2 minItems: 1 items: - const: "tx irq" - const: "rx irq" # Property names starting with '#' must be quoted '#interrupt-cells': # A simple case where the value must always be '2'. # The core schema handles that this must be a single integer. const: 2 interrupt-controller: {} # The core checks this is a boolean, so just have to list it here to be # valid for this binding. clock-frequency: # The type is set in the core schema. Per device schema only need to set # constraints on the possible values. minimum: 100 maximum: 400000 # The value that should be used if the property is not present default: 200 foo-gpios: maxItems: 1 description: A connection of the 'foo' gpio line. vendor,int-property: description: Vendor specific properties must have a description type: integer # A type is also required enum: [2, 4, 6, 8, 10] vendor,bool-property: description: Vendor specific properties must have a description type: boolean required: - compatible - reg - interrupts - interrupt-controller examples: - | /{ compatible = "vendor,soc4-ip", "vendor,soc1-ip"; reg = <0x1000 0x80>, <0x3000 0x80>; reg-names = "core", "aux"; interrupts = <10>; interrupt-controller; }; dt-schema-2025.08/pyproject.toml000066400000000000000000000023131504414563000164540ustar00rootroot00000000000000[build-system] requires = ["setuptools>=61", "setuptools_scm[toml]>=6.2"] build-backend = "setuptools.build_meta" [tool.setuptools_scm] write_to = "dtschema/version.py" [project] name = "dtschema" description = "DeviceTree validation schema and tools" readme = "README.md" requires-python = ">=3.7" license = {file = "LICENSE.txt"} authors = [ {name = "Rob Herring", email = "robh@kernel.org"}, ] classifiers = [ "Programming Language :: Python :: 3", "License :: OSI Approved :: BSD License", "Operating System :: OS Independent", "Intended Audience :: Developers", ] dynamic = ["version"] dependencies = [ "ruamel.yaml>0.15.69", "jsonschema>=4.1.2,<4.18", "rfc3987", "pylibfdt", ] [project.scripts] dt-check-compatible = "dtschema.check_compatible:main" dt-cmp-schema = "dtschema.cmp_schema:main" dt-doc-validate = "dtschema.doc_validate:main" dt-extract-example = "dtschema.extract_example:main" dt-extract-props = "dtschema.extract_props:main" dt-mk-schema = "dtschema.mk_schema:main" dt-validate = "dtschema.dtb_validate:main" dtb2py = "dtschema.dtb2py:main" [project.urls] Homepage="https://github.com/devicetree-org/dt-schema" Source="https://github.com/devicetree-org/dt-schema" dt-schema-2025.08/test/000077500000000000000000000000001504414563000145205ustar00rootroot00000000000000dt-schema-2025.08/test/bootphases.dts000066400000000000000000000006121504414563000174020ustar00rootroot00000000000000// SPDX-License-Identifier: BSD-2-Clause // Copyright 2022 Google LLC // An attempt to provide a device tree to validate the phase properties // dtc -O dtb -o test.dtb test/bootphases.dts && tools/dt-validate test.dtb /dts-v1/; / { model = "none"; compatible = "foo"; #address-cells = <1>; #size-cells = <1>; some-device { compatible = "vendor,soc1-ip"; bootph-pre-sram; }; }; dt-schema-2025.08/test/child-node-fail.dts000066400000000000000000000034711504414563000201600ustar00rootroot00000000000000// SPDX-License-Identifier { BSD-2-Clause // Copyright 2018 Linaro Ltd. // Copyright 2018-2022 Arm Ltd. /dts-v1/; /plugin/; // silence any missing phandle references / { model = "none"; compatible = "foo"; #address-cells = <1>; #size-cells = <1>; bad-child-node-missing-req-prop { compatible = "vendor,node-with-child-node"; child-node-fixed-name { vendor,optional-property = <1234>; }; }; bad-child-node-property-value { compatible = "vendor,node-with-child-node"; child-node-fixed-name { vendor,required-property = "a string"; }; }; bad-parent-node-property { compatible = "vendor,node-with-child-node"; foo = <0 1>; child-node-fixed-name { vendor,required-property = <1234>; }; }; bad-child-node-reg-size { compatible = "vendor,node-with-child-node"; child-node-fixed-name { vendor,required-property = <1234>; }; child-node@0 { compatible = "a-child-compatible"; reg = <0 1>, <1 1>; vendor,a-child-property = <2>; }; }; bad-child-node-u32-property { compatible = "vendor,node-with-child-node"; child-node-fixed-name { vendor,required-property = <1234>; }; child-node@0 { compatible = "a-child-compatible"; reg = <0>; vendor,a-child-property = <1>; }; }; bad-child-node-u32-property2 { compatible = "vendor,node-with-child-node"; child-node-fixed-name { vendor,required-property = <1234>; }; child-node@0 { compatible = "a-child-compatible"; reg = <0>; vendor,a-child-property2 = <1>; }; }; bad-child-node-string-property { compatible = "vendor,node-with-child-node"; child-node-fixed-name { vendor,required-property = <1234>; }; child-node@0 { compatible = "a-child-compatible"; reg = <0>; vendor,a-child-property = <2>; vendor,a-child-string-property = "a-string", "bad-string"; }; }; }; dt-schema-2025.08/test/child-node.dts000066400000000000000000000011161504414563000172410ustar00rootroot00000000000000// SPDX-License-Identifier: BSD-2-Clause // Copyright 2018 Linaro Ltd. // Copyright 2018-2022 Arm Ltd. /dts-v1/; /plugin/; // silence any missing phandle references / { model = "none"; compatible = "foo"; #address-cells = <1>; #size-cells = <1>; good-child-node-test { compatible = "vendor,node-with-child-node"; child-node-fixed-name { vendor,required-property = <1234>; }; child-node@0 { compatible = "a-child-compatible"; reg = <0>; vendor,a-child-property = <2>; vendor,a-child-property2 = <4>; vendor,a-child-string-property = "a-string"; }; }; }; dt-schema-2025.08/test/conditionals-allof-fail.dts000066400000000000000000000015251504414563000217310ustar00rootroot00000000000000// SPDX-License-Identifier { BSD-2-Clause // Copyright 2019 Maxime Ripard // Copyright 2022 Arm Ltd. /dts-v1/; /plugin/; // silence any missing phandle references / { model = "none"; compatible = "none"; #address-cells = <1>; #size-cells = <1>; bad-child-node-wrong-vendor-property { compatible = "vendor,conditionals-allof-test-controller"; vendor,property = "test"; }; bad-child-node-too-long { compatible = "vendor,conditionals-allof-test-controller"; vendor,property = "test1234", "test12345678"; }; bad-child-node-second-wrong-vendor-property { compatible = "vendor,second-conditionals-allof-test-controller"; vendor,property = "test"; vendor,other-property; }; bad-child-node-second-missing-other-property { compatible = "vendor,second-conditionals-allof-test-controller"; vendor,property = "test5678"; }; };dt-schema-2025.08/test/conditionals-allof-pass.dts000066400000000000000000000010161504414563000217570ustar00rootroot00000000000000// SPDX-License-Identifier { BSD-2-Clause // Copyright 2019 Maxime Ripard // Copyright 2022 Arm Ltd. /dts-v1/; /plugin/; // silence any missing phandle references / { model = "none"; compatible = "none"; #address-cells = <1>; #size-cells = <1>; test-controller { compatible = "vendor,conditionals-allof-test-controller"; vendor,property = "test1234"; }; second-test-controller { compatible = "vendor,second-conditionals-allof-test-controller"; vendor,property = "test5678"; vendor,other-property; }; }; dt-schema-2025.08/test/conditionals-single-fail.dts000066400000000000000000000011531504414563000221120ustar00rootroot00000000000000// SPDX-License-Identifier { BSD-2-Clause // Copyright 2019 Maxime Ripard // Copyright 2022 Arm Ltd. /dts-v1/; /plugin/; // silence any missing phandle references / { model = "none"; compatible = "none"; #address-cells = <1>; #size-cells = <1>; bad-child-node-wrong-vendor-property { compatible = "vendor,test-controller"; vendor,property = "test"; }; bad-child-node-too-long { compatible = "vendor,test-controller"; vendor,property = "test1234", "test12345678"; }; bad-child-node-second-wrong-vendor-property { compatible = "vendor,second-test-controller"; vendor,property = "test"; }; }; dt-schema-2025.08/test/conditionals-single-pass.dts000066400000000000000000000007171504414563000221520ustar00rootroot00000000000000// SPDX-License-Identifier { BSD-2-Clause // Copyright 2019 Maxime Ripard // Copyright 2022 Arm Ltd. /dts-v1/; /plugin/; // silence any missing phandle references / { model = "none"; compatible = "none"; #address-cells = <1>; #size-cells = <1>; test-controller { compatible = "vendor,test-controller"; vendor,property = "test1234"; }; second-test-controller { compatible = "vendor,second-test-controller"; vendor,property = "test5678"; }; }; dt-schema-2025.08/test/device-fail.dts000066400000000000000000000075501504414563000174130ustar00rootroot00000000000000// SPDX-License-Identifier: BSD-2-Clause // Copyright 2018 Linaro Ltd. // Copyright 2018-2022 Arm Ltd. /dts-v1/; /plugin/; // silence any missing phandle references / { model = "none"; compatible = "none"; #address-cells = <1>; #size-cells = <1>; interrupt-controller; #interrupt-cells = <1>; interrupt-controller@0 { // bad-num-interrupts-test: compatible = "vendor,soc1-ip"; reg = <0 0>; interrupt-controller; #interrupt-cells = <2>; interrupts = <10>, <11>, <12>; }; interrupt-controller@1 { // bad-interrupt-type-test: compatible = "vendor,soc1-ip"; reg = <1 0>; interrupt-controller; #interrupt-cells = <2>; interrupts = "string"; }; interrupt-controller@2 { // bad-no-interrupt-cells-test: compatible = "vendor,soc1-ip"; reg = <2 0>; interrupt-controller; interrupts = <10>; }; interrupt-controller@3 { // bad-compatible-test: compatible = "vendor,soc4-ip", "vendor,soc3-ip"; reg = <3 0>; interrupt-controller; #interrupt-cells = <2>; interrupts = <10>; }; interrupt-controller@4 { // bad-compatible-order-test: compatible = "vendor,soc1-ip", "vendor,soc3-ip"; reg = <4 0>; interrupt-controller; #interrupt-cells = <2>; interrupts = <10>; }; interrupt-controller@5 { // bad-compatible-missing-test: compatible = "vendor,soc3-ip"; reg = <5 0>; interrupt-controller; #interrupt-cells = <2>; interrupts = <10>; }; interrupt-controller@6 { // bad-compatible-value-test: compatible = "vendor,undocumented-compatible string", "vendor,soc1-ip"; reg = <6 0>; interrupt-controller; #interrupt-cells = <2>; interrupts = <10>; }; interrupt-controller@7 { // bad-clock-freqency-test: compatible = "vendor,soc1-ip"; reg = <7 0>; interrupt-controller; #interrupt-cells = <2>; interrupts = <10>; clock-frequency = <1>; }; interrupt-controller@8 { // bad-interrupt-names-test1: compatible = "vendor,soc1-ip"; reg = <8 0>; interrupt-controller; #interrupt-cells = <2>; interrupt-names = "a irq"; interrupts = <10>; }; interrupt-controller@9 { // bad-interrupt-names-test2: compatible = "vendor,soc1-ip"; reg = <9 0>; interrupt-controller; #interrupt-cells = <2>; interrupt-names = "tx irq", "rx irq", "bad irq"; interrupts = <10>; }; bad-vendor-bool-prop-test { compatible = "vendor,soc1-ip"; vendor,bool-prop = "true"; }; bad-vendor-int-test { compatible = "vendor,soc1-ip"; vendor,int-prop = <5>; }; bad-vendor-int-array-test { compatible = "vendor,soc1-ip"; vendor,int-array-prop = <5>, <4>; }; bad-vendor-int-array-2-test { compatible = "vendor,soc1-ip"; vendor,int-array-prop-2 = <5 4>; }; bad-vendor-int-array-3-test { compatible = "vendor,soc1-ip"; vendor,int-array-size-only-prop = <5 6 7 8 9 10>; }; bad-vendor-string-test { compatible = "vendor,soc1-ip"; vendor,string-prop = "foobaz"; }; bad-vendor-string-list-test { compatible = "vendor,soc1-ip"; vendor,string-list-prop = "foobar"; }; bad-vendor-int8-prop-test { compatible = "vendor,soc1-ip"; vendor,int8-prop = /bits/ 16 <1>; }; bad-vendor-int8-array-prop-test { compatible = "vendor,soc1-ip"; vendor,int8-array-prop = /bits/ 8 <1>; }; bad-vendor-int16-prop-test { compatible = "vendor,soc1-ip"; vendor,int16-prop = <1>; }; bad-vendor-int16-array-prop-test { compatible = "vendor,soc1-ip"; vendor,int16-array-prop = /bits/ 16 <1 2 3>; }; bad-vendor-int64-prop-test { compatible = "vendor,soc1-ip"; vendor,int64-prop = /bits/ 64 <0x123>; }; bad-vendor-phandle-prop-test { compatible = "vendor,soc1-ip"; vendor,phandle-prop = <&foo 0>, <1>; vendor,phandle-array-prop = <&foo>; }; bad-vendor-phandle-args-len-test { compatible = "vendor,soc1-ip"; vendor,phandle-with-fixed-cells = <&foo 2>; }; bad-vendor-phandle-args-len-test2 { compatible = "vendor,soc1-ip"; vendor,phandle-with-fixed-cells = <&foo 2 3>, <&foo 1>; }; }; dt-schema-2025.08/test/device.dts000066400000000000000000000031231504414563000164720ustar00rootroot00000000000000// SPDX-License-Identifier: BSD-2-Clause // Copyright 2018 Linaro Ltd. // Copyright 2018-2022 Arm Ltd. /dts-v1/; /plugin/; // silence any missing phandle references / { model = "none"; compatible = "foo"; #address-cells = <1>; #size-cells = <1>; interrupt-controller; #interrupt-cells = <1>; interrupt-controller@0 { compatible = "vendor,soc4-ip", "vendor,soc1-ip"; reg = <0x0 0x4>, <0x8 0x4>; reg-names = "coreAAA", "aux"; interrupt-controller; #interrupt-cells = <2>; interrupts = <10>, <11>; some-gpios = <&gpio0 0>, <&gpio0 1 0>; clocks = <&clk0>; clock-names = "clk1" , "clk2"; vendor,bool-prop; vendor,int-prop = <3>; vendor,int-array-prop = <5 6 7 8>; vendor,int-array-prop-2 = <5 10>; vendor,int-array-size-only-prop = <2 3>; vendor,string-prop = "foo"; vendor,int8-prop = /bits/ 8 <1>; vendor,int8-array-prop = /bits/ 8 <1 2>; vendor,int16-prop = /bits/ 16 <1>; vendor,int16-array-prop = /bits/ 16 <1 2>; vendor,int64-prop = /bits/ 64 <0x100000000>; vendor,phandle-prop = <&a_phandle>; vendor,phandle-array-prop = <&a_phandle>, <&a_phandle>; vendor,string-list-prop = "foobar", "foobaz"; vendor,phandle-with-fixed-cells = <&a_phandle 2 3>; vendor,int64-array-prop = /bits/ 64 <0x10000000 0x1>; }; interrupt-controller@10 { compatible = "vendor,soc1-ip"; interrupt-controller; reg = <0x10 0x4>, <0x8 0x4>; #interrupt-cells = <2>; interrupts = <10>; interrupt-names = "tx irq"; vendor,int-array-prop = <5>, <6>, <7>, <8>; vendor,int-array-size-only-prop = <2>, <3>, <4>; vendor,int64-array-prop = /bits/ 64 <0x10000000 0x1>; }; };dt-schema-2025.08/test/schemas/000077500000000000000000000000001504414563000161435ustar00rootroot00000000000000dt-schema-2025.08/test/schemas/bad-example.yaml000066400000000000000000000027121504414563000212100ustar00rootroot00000000000000# SPDX-License-Identifier: BSD-2-Clause # Copyright 2018 Linaro Ltd. # Copyright 2018 Arm Ltd. %YAML 1.2 --- $id: http://devicetree.org/schemas/bad-example.yaml $schema: http://json-schema.org/draft-07/schema# title: 0 maintainers: - Bob - 12 - will.e@acme.co.uk description: - The description should not be a sequence. - A sequence is also called an array. properties: compatible: type: integer description: Compatible strings for the board example. enum: - 123 oneOf: - items: - unknown: {} - enum: - 456 - "example,board1-with-soc1" - "example,board2-with-soc1" - const: 789 - items: - enum: - 987 - "example,board-with-soc2" - const: "example,soc2" additionalItems: false minItems: 0 maxItems: 2 reg: minItems: 2 maxItems: 0 interrupts: description: 0 minItems: 0 interrupt-names: rob: {} minItems: 3 items: - "rob" - const: "string_with_illegal characters #?" - const: 0 interrupt-controller: type: integer '#interrupt-cells': const: 'foo' description: 0 gpio-controller: const: 'foo' some-gpio: minItems: 0 some-gpios: description: 0 another-property: description: 0 vendor,property: type: boolean required: - model - psci - cpus - 0 bad-key: Only known keys are allowed. dt-schema-2025.08/test/schemas/child-node-example.yaml000066400000000000000000000035121504414563000224670ustar00rootroot00000000000000# SPDX-License-Identifier: BSD-2-Clause # Copyright 2018 Linaro Ltd. # Copyright 2018 Arm Ltd. %YAML 1.2 --- $id: http://devicetree.org/schemas/child-node-example.yaml# $schema: http://devicetree.org/meta-schemas/core.yaml# title: A Device with Child Nodes maintainers: - Rob Herring properties: compatible: items: - const: vendor,node-with-child-node foo: const: 2 reg: items: - description: core regs - description: aux regs child-node-fixed-name: type: object properties: vendor,required-property: $ref: /schemas/types.yaml#/definitions/uint32 description: test vendor,optional-property: $ref: /schemas/types.yaml#/definitions/uint32 description: test required: - vendor,required-property patternProperties: '^child-node@.*$': type: object description: This is a child node. properties: compatible: items: - const: a-child-compatible vendor,a-child-property: allOf: - $ref: /schemas/types.yaml#/definitions/uint32 - const: 2 description: test vendor,a-child-property2: allOf: - $ref: /schemas/types.yaml#/definitions/uint32 - oneOf: - description: | Testing for 'oneOf', otherwise this could just be an enum const: 2 - const: 4 description: test reg: maxItems: 1 child-property: type: boolean vendor,a-child-string-property: description: a child string property allOf: - $ref: /schemas/types.yaml#/definitions/string - const: "a-string" required: - vendor,a-child-property - reg required: - compatible - child-node-fixed-name additionalProperties: false dt-schema-2025.08/test/schemas/conditionals-allof-example.yaml000066400000000000000000000021341504414563000242410ustar00rootroot00000000000000# SPDX-License-Identifier: BSD-2-Clause # Copyright 2019 Maxime Ripard %YAML 1.2 --- $id: http://devicetree.org/schemas/conditionals-allof-example.yaml# $schema: http://devicetree.org/meta-schemas/core.yaml# title: Test for multiple conditionals statements maintainers: - Maxime Ripard properties: compatible: enum: - vendor,conditionals-allof-test-controller - vendor,second-conditionals-allof-test-controller vendor,property: description: A vendor prop $ref: /schemas/types.yaml#/definitions/string vendor,other-property: description: Other vendor prop type: boolean additionalProperties: false allOf: - if: properties: compatible: const: vendor,conditionals-allof-test-controller then: properties: vendor,property: const: test1234 else: properties: vendor,property: const: test5678 - if: properties: compatible: const: vendor,second-conditionals-allof-test-controller then: required: - vendor,other-property dt-schema-2025.08/test/schemas/conditionals-single-example.yaml000066400000000000000000000013611504414563000244260ustar00rootroot00000000000000# SPDX-License-Identifier: BSD-2-Clause # Copyright 2019 Maxime Ripard %YAML 1.2 --- $id: http://devicetree.org/schemas/conditionals-single-example.yaml# $schema: http://devicetree.org/meta-schemas/core.yaml# title: Test for a single conditionals statement maintainers: - Maxime Ripard properties: compatible: enum: - vendor,test-controller - vendor,second-test-controller vendor,property: description: A vendor prop $ref: /schemas/types.yaml#/definitions/string if: properties: compatible: const: vendor,test-controller then: properties: vendor,property: const: test1234 else: properties: vendor,property: const: test5678 additionalProperties: false dt-schema-2025.08/test/schemas/good-example.yaml000066400000000000000000000126461504414563000214210ustar00rootroot00000000000000# SPDX-License-Identifier: BSD-2-Clause # Copyright 2018 Linaro Ltd. # Copyright 2018 Arm Ltd. %YAML 1.2 --- $id: http://devicetree.org/schemas/good-example.yaml# $schema: http://devicetree.org/meta-schemas/core.yaml# title: Test device with vendor properties of different types description: A more detailed description for a good binding example. maintainers: - Rob Herring properties: compatible: oneOf: - items: - enum: - vendor,soc4-ip - vendor,soc3-ip - vendor,soc2-ip - enum: - vendor,soc1-ip - items: - enum: - vendor,soc1-ip - items: - false - not: {} description: Needs a specific compatible - const: vendor,soc1-ip reg: maxItems: 2 reg-names: items: - const: "coreAAA" - const: "aux" interrupts: minItems: 1 items: - description: 1st irq - description: 2nd irq interrupt-names: minItems: 1 items: - const: "tx irq" - const: "rx irq" '#interrupt-cells': const: 2 interrupt-controller: {} clock-frequency: minimum: 100 maximum: 400000 clocks: minItems: 1 items: - description: 1st clock - description: 2nd clock clock-names: items: - const: "clk1" - const: "clk2" '#clock-cells': const: 1 clock-output-names: minItems: 1 maxItems: 2 some-gpios: maxItems: 2 a-single-gpios: description: A GPIO that does something maxItems: 1 vendor,bool-prop: $ref: /schemas/types.yaml#/definitions/flag description: A vendor specific boolean property vendor,int-prop: $ref: /schemas/types.yaml#/definitions/uint32 enum: [ 1, 2, 3 ] description: Vendor specific single cell integer property vendor,int-array-prop: $ref: /schemas/types.yaml#/definitions/uint32-array items: minimum: 5 maximum: 10 description: Vendor specific integer array property vendor,int-array-prop-2: $ref: /schemas/types.yaml#/definitions/uint32-array items: - const: 5 - const: 10 description: Vendor specific integer array property vendor,int-array-size-only-prop: $ref: /schemas/types.yaml#/definitions/uint32-array minItems: 2 maxItems: 5 description: Vendor specific integer array property with only a size range. This can use either form of brackets. vendor,string-prop: $ref: /schemas/types.yaml#/definitions/string enum: - foo - bar description: Vendor specific single string property vendor,string-list-prop: $ref: /schemas/types.yaml#/definitions/string-array items: - const: foobar - const: foobaz description: Vendor specific string list property vendor,int8-prop: $ref: /schemas/types.yaml#/definitions/uint8 description: Vendor specific 8-bit integer property vendor,int8-array-prop: $ref: /schemas/types.yaml#/definitions/uint8-array minItems: 2 maxItems: 3 description: A vendor specific uint8 array property with 2 or 3 entries vendor,int16-prop: $ref: /schemas/types.yaml#/definitions/uint16 enum: [ 1, 2, 3 ] description: Vendor specific 16-bit integer property vendor,int16-array-prop: $ref: /schemas/types.yaml#/definitions/uint16-array items: - const: 1 - const: 2 description: Vendor specific 16-bit integer array property vendor,int64-prop: $ref: /schemas/types.yaml#/definitions/uint64 minimum: 0x1234 description: Vendor specific 16-bit integer property vendor,int64-array-prop: $ref: /schemas/types.yaml#/definitions/uint64-array description: Vendor specific 64-bit integer array property vendor,phandle-prop: $ref: /schemas/types.yaml#/definitions/phandle description: Vendor specific single cell phandle property vendor,phandle-array-prop: $ref: /schemas/types.yaml#/definitions/phandle-array minItems: 2 items: maxItems: 1 description: Vendor specific array of phandles property vendor,phandle-with-fixed-cells: $ref: /schemas/types.yaml#/definitions/phandle-array items: - items: - description: the phandle to something - description: the 1st cell data - description: the 2nd cell data description: Vendor specific array of phandles property required: - compatible additionalProperties: false examples: - | /dts-v1/; /{ model = "ARM Juno development board (r0)"; compatible = "arm,juno", "arm,vexpress"; interrupt-parent = <&gic>; #address-cells = <2>; #size-cells = <2>; cpus { #address-cells = <2>; #size-cells = <0>; A57_0: cpu@0 { compatible = "arm,cortex-a57","arm,armv8"; reg = <0x0 0x0>; device_type = "cpu"; enable-method = "psci"; }; ..... A53_0: cpu@100 { compatible = "arm,cortex-a53","arm,armv8"; reg = <0x0 0x100>; device_type = "cpu"; enable-method = "psci"; }; ..... }; }; dt-schema-2025.08/test/simple-bus-fail.dts000066400000000000000000000007331504414563000202300ustar00rootroot00000000000000// SPDX-License-Identifier: BSD-2-Clause // Copyright 2019-2022 Arm Ltd. /dts-v1/; /plugin/; // silence any missing phandle references / { model = "none"; compatible = "none"; #address-cells = <1>; #size-cells = <1>; bus@8000 { compatible = "simple-bus"; #address-cells = <1>; #size-cells = <1>; ranges = <0 0x8000 0x4000>; child@200 {}; }; }; dt-schema-2025.08/test/simple-bus-pass.dts000066400000000000000000000015031504414563000202570ustar00rootroot00000000000000// SPDX-License-Identifier: BSD-2-Clause // Copyright 2019-2022 Arm Ltd. /dts-v1/; /plugin/; // silence any missing phandle references / { model = "none"; compatible = "none"; #address-cells = <1>; #size-cells = <1>; bus@1000 { compatible = "simple-bus"; #address-cells = <1>; #size-cells = <1>; ranges = <0 0x1000 0x4000>; child@0 { #address-cells = <1>; #size-cells = <1>; ranges = <0 0 0x100>; grand-child@0 { reg = <0 0x100>; }; }; child@100 { reg = <0x100 0x100>; }; }; }; dt-schema-2025.08/test/test-dt-validate.py000077500000000000000000000135701504414563000202560ustar00rootroot00000000000000#!/usr/bin/env python3 # # Testcases for the Devicetree schema files and validation library # # Copyright 2018 Arm Ltd. # # SPDX-License-Identifier: BSD-2-Clause # # Testcases are executed by running 'make test' from the top level directory of this repo. import unittest import os import copy import glob import sys import subprocess import tempfile basedir = os.path.dirname(__file__) import jsonschema import ruamel.yaml import dtschema dtschema_dir = os.path.dirname(dtschema.__file__) yaml = ruamel.yaml.YAML(typ='safe') def load(filename): with open(filename, 'r', encoding='utf-8') as f: return yaml.load(f.read()) class TestDTMetaSchema(unittest.TestCase): def setUp(self): self.schema = dtschema.DTSchema(os.path.join(basedir, 'schemas/good-example.yaml')) self.bad_schema = dtschema.DTSchema(os.path.join(basedir, 'schemas/bad-example.yaml')) def test_all_metaschema_valid(self): '''The metaschema must all be a valid Draft2019-09 schema''' for filename in glob.iglob(os.path.join(dtschema_dir, 'meta-schemas/**/*.yaml'), recursive=True): with self.subTest(schema=filename): schema = load(filename) jsonschema.Draft201909Validator.check_schema(schema) def test_required_properties(self): self.schema.is_valid(strict=True) def test_required_property_missing(self): for key in self.schema.keys(): if key in ['$schema', 'properties', 'required', 'description', 'examples', 'additionalProperties']: continue with self.subTest(k=key): schema_tmp = copy.deepcopy(self.schema) del schema_tmp[key] self.assertRaises(jsonschema.SchemaError, schema_tmp.is_valid, strict=True) def test_bad_schema(self): '''bad-example.yaml is all bad. There is no condition where it should pass validation''' self.assertRaises(jsonschema.SchemaError, self.bad_schema.is_valid, strict=True) def test_bad_properties(self): for key in self.bad_schema.keys(): if key in ['$schema', 'properties']: continue with self.subTest(k=key): schema_tmp = copy.deepcopy(self.schema) schema_tmp[key] = self.bad_schema[key] self.assertRaises(jsonschema.SchemaError, schema_tmp.is_valid, strict=True) bad_props = self.bad_schema['properties'] schema_tmp = copy.deepcopy(self.schema) for key in bad_props.keys(): with self.subTest(k="properties/"+key): schema_tmp['properties'] = self.schema['properties'].copy() schema_tmp['properties'][key] = bad_props[key] self.assertRaises(jsonschema.SchemaError, schema_tmp.is_valid, strict=True) class TestDTSchema(unittest.TestCase): def test_binding_schemas_valid(self): '''Test that all schema files under ./dtschema/schemas/ validate against the DT metaschema''' for filename in glob.iglob(os.path.join(dtschema_dir, 'schemas/**/*.yaml'), recursive=True): with self.subTest(schema=filename): dtschema.DTSchema(filename).is_valid(strict=True) def test_binding_schemas_refs(self): '''Test that all schema files under ./dtschema/schemas/ have valid references''' for filename in glob.iglob(os.path.join(dtschema_dir, 'schemas/**/*.yaml'), recursive=True): with self.subTest(schema=filename): dtschema.DTSchema(filename).check_schema_refs() def test_binding_schemas_id_is_unique(self): '''Test that all schema files under ./dtschema/schemas/ validate against the DT metaschema''' ids = [] for filename in glob.iglob(os.path.join(dtschema_dir, 'schemas/**/*.yaml'), recursive=True): with self.subTest(schema=filename): schema = load(filename) self.assertEqual(ids.count(schema['$id']), 0) ids.append(schema['$id']) def test_binding_schemas_valid_draft7(self): '''Test that all schema files under ./dtschema/schemas/ validate against the Draft7 metaschema The DT Metaschema is supposed to force all schemas to be valid against Draft7. This test makes absolutely sure that they are. ''' for filename in glob.iglob(os.path.join(dtschema_dir, 'schemas/**/*.yaml'), recursive=True): with self.subTest(schema=filename): schema = load(filename) jsonschema.Draft7Validator.check_schema(schema) class TestDTValidate(unittest.TestCase): def setUp(self): self.validator = dtschema.DTValidator([ os.path.join(os.path.abspath(basedir), "schemas/")]) def check_node(self, nodename, node): if nodename == "/" or nodename.startswith('__'): return node['$nodename'] = [ nodename ] self.validator.validate(node) def check_subtree(self, nodename, subtree): self.check_node(nodename, subtree) for name,value in subtree.items(): if isinstance(value, dict): self.check_subtree(name, value) def test_dtb_validation(self): '''Test that all DT files under ./test/ validate against the DT schema (DTB)''' for filename in glob.iglob('test/*.dts'): with self.subTest(schema=filename): expect_fail = "-fail" in filename res = subprocess.run(['dtc', '-Odtb', filename], capture_output=True) testtree = self.validator.decode_dtb(res.stdout) self.assertEqual(res.returncode, 0, msg='dtc failed:\n' + res.stderr.decode()) if expect_fail: with self.assertRaises(jsonschema.ValidationError): self.check_subtree('/', testtree[0]) else: self.assertIsNone(self.check_subtree('/', testtree[0])) if __name__ == '__main__': unittest.main() dt-schema-2025.08/tools/000077500000000000000000000000001504414563000147015ustar00rootroot00000000000000dt-schema-2025.08/tools/dt-prop-populate000077500000000000000000000140761504414563000200530ustar00rootroot00000000000000#!/usr/bin/python3 # SPDX-License-Identifier: BSD-2-Clause # Copyright 2018 Linaro Ltd. import argparse import os import sys import glob import re from ruamel import yaml import dtschema bindings_dir = 'Bindings' binding_file = {} class schema_group(): def process_node(self, tree, nodename, node, filename): if not 'compatible' in node.keys(): return if binding_file.get(node['compatible'][0]): return for compat in node['compatible']: if compat in ['isa', 'simple-bus', 'cfi-flash']: return match_compat = node['compatible'][0] best_file_match = '' for root, dirs, files in os.walk(bindings_dir): for file in files: if os.path.splitext(os.path.basename(file))[0] in node['compatible']: best_file_match = os.path.join(root, file) break if best_file_match: break if not best_file_match: binding_file[match_compat] = [] for file,data in historical.items(): for line in data.splitlines(): if not re.search(match_compat, line): continue binding_file[match_compat].append(file) if binding_file[match_compat]: best_file_match = max(set(binding_file[match_compat]), key=binding_file[match_compat].count) if not best_file_match: # print("not found: ", node['compatible']) return print(match_compat + ': ' + best_file_match) f = open(best_file_match, 'r+', encoding='utf-8') rawfile = f.read() top_comment = rawfile.partition('%YAML')[0] try: yamldata = yml.load(rawfile) except (yaml.scanner.ScannerError, yaml.parser.ParserError) as exc: print(best_file_match + ": ", exc) return except yaml.YAMLError as exc: print(best_file_match + ":", exc) return for key in node.keys(): # skip child nodes if isinstance(node[key], dict): continue if key in [ 'status', 'phandle' ]: continue; if key in yamldata['properties'].keys() and yamldata['properties'][key] != {}: if key == 'compatible': if 'const' in yamldata['properties'][key]['items'][0]: if yamldata['properties'][key]['items'][0]['const'] != match_compat: yamldata['properties'][key]['items'][0] = { 'enum': [ match_compat, yamldata['properties'][key]['items'][0]['const'] ] } #print(yamldata['properties'][key]['items'][0]) else: matched = False for c in yamldata['properties'][key]['items'][0]['enum']: if match_compat in c: matched = True break if matched: continue yamldata['properties'][key]['items'][0]['enum'].append(match_compat) #print(yamldata['properties'][key]['items'][0]) continue yamldata['properties'][key] = {} if isinstance(node[key], list) and isinstance(node[key][0], str): count = len(node[key]) str_items = [] for val in node[key]: str_items.append({ 'const': val }) yamldata['properties'][key] = { 'items': str_items } if re.search('^[a-zA-Z].*,', key): # vendor specific properties must have description yamldata['properties'][key]['description'] = 'FIXME' if isinstance(node[key], bool): yamldata['properties'][key]['type'] = 'boolean' if re.search('^#.*-cells$', key): yamldata['properties'][key]['const'] = node[key][0][0] if key == 'reg' and isinstance(node[key][0], list): count = len(node[key]) yamldata['properties'][key] = { 'items': [ 'description' : 'FIXME' ] } f.seek(0) print(top_comment, file=f, end="") yml.dump(yamldata, f) f.truncate() def process_subtree(self, tree, nodename, subtree, filename): self.process_node(tree, nodename, subtree, filename) for name,value in subtree.items(): if type(value) == yaml.comments.CommentedMap: self.process_subtree(tree, name, value, filename) def process_tree(self, filename, dt): for subtree in dt: self.process_subtree(subtree, "/", subtree, filename) if __name__ == "__main__": sg = schema_group() ap = argparse.ArgumentParser() ap.add_argument("yamldt", type=str, help="Filename of YAML encoded devicetree input file") args = ap.parse_args() yml = yaml.YAML() # Setup formatting settings yml.indent(mapping=2, sequence=4, offset=2) yml.explicit_start=True yml.preserve_quotes=True yml.version=(1,2) # assuming yaml docs have the old binding doc historical = {} for file in glob.iglob(bindings_dir + "/**/*.yaml", recursive=True): if not os.path.isfile(file): continue # if the filename has a comma, then it's probably a compatible # string and we should only match it with the algorithm above. if ',' in os.path.basename(file): continue rawfile = open(file, 'r', encoding='utf-8').read() try: historical[file] = yml.load(rawfile)['historical'] except: continue if os.path.isdir(args.yamldt): for filename in glob.iglob(args.yamldt + "/**/*.dt.yaml", recursive=True): testtree = dtschema.load(open(filename, encoding='utf-8').read()) sg.process_tree(filename, testtree) else: testtree = dtschema.load(open(args.yamldt, encoding='utf-8').read()) sg.process_tree(args.yamldt, testtree) dt-schema-2025.08/tools/yaml-format000077500000000000000000000041271504414563000170630ustar00rootroot00000000000000#!/usr/bin/env python3 # SPDX-License-Identifier: BSD-2-Clause # Copyright 2018 Linaro Ltd. # Copyright 2018 Arm Ltd. import os import sys import argparse import glob from ruamel import yaml def eprint(filename, *args, **kwargs): print(filename + ": warning:", *args, file=sys.stderr, **kwargs) def yaml_format(file, in_place): yml = yaml.YAML() # Setup formatting settings yml.indent(mapping=2, sequence=4, offset=2) yml.explicit_start=True yml.explicit_end=True yml.preserve_quotes=True yml.version=(1,2) yml.width=70 rawfile = open(file, encoding='utf-8').read() top_comment = rawfile.partition('%YAML')[0] print(top_comment, file=sys.stderr) try: yamldata = yml.load(rawfile) except yaml.YAMLError as exc: print(file + ":", exc) exit(-1) yamldata['description'] = yaml.scalarstring.PreservedScalarString(yamldata['description']) # Check that keys are in a defined order key_order = [ "$id", "$schema", "title", "maintainers", "description", "allOf", "properties", "required", "patternProperties" "examples" ]; last_idx = 0 yaml_keys = list(yamldata.keys()) for k in key_order: try: if yaml_keys.index(k) < last_idx: eprint(file, "Expected " + key_order[i] + " for key {0}, found ".format(i) + k) last_idx = yaml_keys.index(k) except: continue if in_place: f = open(file, 'w', encoding='utf-8') else: f = sys.stdout print(top_comment, file=f, end="") yml.dump(yamldata, f) if __name__ == "__main__": ap = argparse.ArgumentParser() ap.add_argument("-i", "--in-place", help="operate in place on ", action="store_true") ap.add_argument("file", type=str, help="Filename of YAML encoded devicetree input file") args = ap.parse_args() if os.path.isdir(args.file): for filename in glob.iglob(args.file + "/**/*.yaml", recursive=True): yaml_format(filename, args.in_place) else: yaml_format(args.file, args.in_place) dt-schema-2025.08/tools/yaml2json000077500000000000000000000013761504414563000165540ustar00rootroot00000000000000#!/usr/bin/env python3 # SPDX-License-Identifier: BSD-2-Clause # Copyright 2018 Linaro Ltd. # Copyright 2018 Arm Ltd. import sys import argparse import ruamel.yaml import json yaml = ruamel.yaml.YAML() if __name__ == "__main__": ap = argparse.ArgumentParser() ap.add_argument('-o', '--output', nargs=1, help="output to specified file") ap.add_argument("file", type=str, help="Filename of YAML encoded devicetree input file") args = ap.parse_args() yamldata = yaml.load(open(args.file, encoding='utf-8').read()) if args.output and args.output[0]: f = open(args.output[0], 'w', encoding='utf-8') else: f = open(args.file.replace('.yaml', '.json'), 'w', encoding='utf-8') json.dump(yamldata, f)