# Copyright (c) 2019 Nordic Semiconductor ASA
# Copyright (c) 2019 Linaro Limited
# SPDX-License-Identifier: BSD-3-Clause

# Tip: You can view just the documentation with 'pydoc3 devicetree.edtlib'

"""
Library for working with devicetrees at a higher level compared to dtlib. Like
dtlib, this library presents a tree of devicetree nodes, but the nodes are
augmented with information from bindings and include some interpretation of
properties. Some of this interpretation is based on conventions established
by the Linux kernel, so the Documentation/devicetree/bindings in the Linux
source code is sometimes good reference material.

Bindings are YAML files that describe devicetree nodes. Devicetree
nodes are usually mapped to bindings via their 'compatible = "..."' property,
but a binding can also come from a 'child-binding:' key in the binding for the
parent devicetree node.

Each devicetree node (dtlib.Node) gets a corresponding edtlib.Node instance,
which has all the information related to the node.

The top-level entry points for the library are the EDT and Binding classes.
See their constructor docstrings for details. There is also a
bindings_from_paths() helper function.
"""

# NOTE: tests/test_edtlib.py is the test suite for this library.

# Implementation notes
# --------------------
#
# A '_' prefix on an identifier in Python is a convention for marking it private.
# Please do not access private things. Instead, think of what API you need, and
# add it.
#
# This module is not meant to have any global state. It should be possible to
# create several EDT objects with independent binding paths and flags. If you
# need to add a configuration parameter or the like, store it in the EDT
# instance, and initialize it e.g. with a constructor argument.
#
# This library is layered on top of dtlib, and is not meant to expose it to
# clients. This keeps the header generation script simple.
#
# General biased advice:
#
# - Consider using @property for APIs that don't need parameters. It makes
#   functions look like attributes, which is less awkward in clients, and makes
#   it easy to switch back and forth between variables and functions.
#
# - Think about the data type of the thing you're exposing. Exposing something
#   as e.g. a list or a dictionary is often nicer and more flexible than adding
#   a function.
#
# - Avoid get_*() prefixes on functions. Name them after the thing they return
#   instead. This often makes the code read more naturally in callers.
#
#   Also, consider using @property instead of get_*().
#
# - Don't expose dtlib stuff directly.
#
# - Add documentation for any new APIs you add.
#
#   The convention here is that docstrings (quoted strings) are used for public
#   APIs, and "doc comments" for internal functions.
#
#   @properties are documented in the class docstring, as if they were
#   variables. See the existing @properties for a template.

from collections import OrderedDict, defaultdict
from copy import deepcopy
import logging
import os
import re

import yaml
try:
    # Use the C LibYAML parser if available, rather than the Python parser.
    # This makes e.g. gen_defines.py more than twice as fast.
    from yaml import CLoader as Loader
except ImportError:
    from yaml import Loader     # type: ignore

from devicetree.dtlib import DT, DTError, to_num, to_nums, Type
from devicetree.grutils import Graph


#
# Public classes
#


class EDT:
    """
    Represents a devicetree augmented with information from bindings.

    These attributes are available on EDT objects:

    nodes:
      A list of Node objects for the nodes that appear in the devicetree

    compat2nodes:
      A collections.defaultdict that maps each 'compatible' string that appears
      on some Node to a list of Nodes with that compatible.

    compat2okay:
      Like compat2nodes, but just for nodes with status 'okay'.

    compat2vendor:
      A collections.defaultdict that maps each 'compatible' string that appears
      on some Node to a vendor name parsed from vendor_prefixes.

    label2node:
      A collections.OrderedDict that maps a node label to the node with
      that label.

    dep_ord2node:
      A collections.OrderedDict that maps an ordinal to the node with
      that dependency ordinal.

    chosen_nodes:
      A collections.OrderedDict that maps the properties defined on the
      devicetree's /chosen node to their values. 'chosen' is indexed by
      property name (a string), and values are converted to Node objects.
      Note that properties of the /chosen node which can't be converted
      to a Node are not included in the value.

    dts_path:
      The .dts path passed to __init__()

    dts_source:
      The final DTS source code of the loaded devicetree after merging nodes
      and processing /delete-node/ and /delete-property/, as a string

    bindings_dirs:
      The bindings directory paths passed to __init__()

    scc_order:
      A list of lists of Nodes. All elements of each list
      depend on each other, and the Nodes in any list do not depend
      on any Node in a subsequent list. Each list defines a Strongly
      Connected Component (SCC) of the graph.

      For an acyclic graph each list will be a singleton. Cycles
      will be represented by lists with multiple nodes. Cycles are
      not expected to be present in devicetree graphs.

    The standard library's pickle module can be used to marshal and
    unmarshal EDT objects.
    """
    def __init__(self, dts, bindings_dirs,
                 warn_reg_unit_address_mismatch=True,
                 default_prop_types=True,
                 support_fixed_partitions_on_any_bus=True,
                 infer_binding_for_paths=None,
                 vendor_prefixes=None,
                 werror=False):
        """EDT constructor.

        dts:
          Path to devicetree .dts file

        bindings_dirs:
          List of paths to directories containing bindings, in YAML format.
          These directories are recursively searched for .yaml files.

        warn_reg_unit_address_mismatch (default: True):
          If True, a warning is logged if a node has a 'reg' property where
          the address of the first entry does not match the unit address of the
          node

        default_prop_types (default: True):
          If True, default property types will be used when a node has no
          bindings.

        support_fixed_partitions_on_any_bus (default True):
          If True, set the Node.bus for 'fixed-partitions' compatible nodes
          to None.  This allows 'fixed-partitions' binding to match regardless
          of the bus the 'fixed-partition' is under.

        infer_binding_for_paths (default: None):
          An iterable of devicetree paths identifying nodes for which bindings
          should be inferred from the node content.  (Child nodes are not
          processed.)  Pass none if no nodes should support inferred bindings.

        vendor_prefixes (default: None):
          A dict mapping vendor prefixes in compatible properties to their
          descriptions. If given, compatibles in the form "manufacturer,device"
          for which "manufacturer" is neither a key in the dict nor a specially
          exempt set of grandfathered-in cases will cause warnings.

        werror (default: False):
          If True, some edtlib specific warnings become errors. This currently
          errors out if 'dts' has any deprecated properties set, or an unknown
          vendor prefix is used.
        """
        self._warn_reg_unit_address_mismatch = warn_reg_unit_address_mismatch
        self._default_prop_types = default_prop_types
        self._fixed_partitions_no_bus = support_fixed_partitions_on_any_bus
        self._infer_binding_for_paths = set(infer_binding_for_paths or [])
        self._werror = bool(werror)
        self._vendor_prefixes = vendor_prefixes or {}

        self.dts_path = dts
        self.bindings_dirs = bindings_dirs

        try:
            self._dt = DT(dts)
        except DTError as e:
            raise EDTError(e) from e
        _check_dt(self._dt)

        self._init_compat2binding()
        self._init_nodes()
        self._init_graph()
        self._init_luts()

        self._check()

    def get_node(self, path):
        """
        Returns the Node at the DT path or alias 'path'. Raises EDTError if the
        path or alias doesn't exist.
        """
        try:
            return self._node2enode[self._dt.get_node(path)]
        except DTError as e:
            _err(e)

    @property
    def chosen_nodes(self):
        ret = OrderedDict()

        try:
            chosen = self._dt.get_node("/chosen")
        except DTError:
            return ret

        for name, prop in chosen.props.items():
            try:
                node = prop.to_path()
            except DTError:
                # DTS value is not phandle or string, or path doesn't exist
                continue

            ret[name] = self._node2enode[node]

        return ret

    def chosen_node(self, name):
        """
        Returns the Node pointed at by the property named 'name' in /chosen, or
        None if the property is missing
        """
        return self.chosen_nodes.get(name)

    @property
    def dts_source(self):
        return f"{self._dt}"

    def __repr__(self):
        return f"<EDT for '{self.dts_path}', binding directories " \
            f"'{self.bindings_dirs}'>"

    @property
    def scc_order(self):
        try:
            return self._graph.scc_order()
        except Exception as e:
            raise EDTError(e)

    def _init_graph(self):
        # Constructs a graph of dependencies between Node instances,
        # which is usable for computing a partial order over the dependencies.
        # The algorithm supports detecting dependency loops.
        #
        # Actually computing the SCC order is lazily deferred to the
        # first time the scc_order property is read.

        self._graph = Graph()

        for node in self.nodes:
            # A Node always depends on its parent.
            for child in node.children.values():
                self._graph.add_edge(child, node)

            # A Node depends on any Nodes present in 'phandle',
            # 'phandles', or 'phandle-array' property values.
            for prop in node.props.values():
                if prop.type == 'phandle':
                    self._graph.add_edge(node, prop.val)
                elif prop.type == 'phandles':
                    for phandle_node in prop.val:
                        self._graph.add_edge(node, phandle_node)
                elif prop.type == 'phandle-array':
                    for cd in prop.val:
                        if cd is None:
                            continue
                        self._graph.add_edge(node, cd.controller)

            # A Node depends on whatever supports the interrupts it
            # generates.
            for intr in node.interrupts:
                self._graph.add_edge(node, intr.controller)

    def _init_compat2binding(self):
        # Creates self._compat2binding, a dictionary that maps
        # (<compatible>, <bus>) tuples (both strings) to Binding objects.
        #
        # The Binding objects are created from YAML files discovered
        # in self.bindings_dirs as needed.
        #
        # For example, self._compat2binding["company,dev", "can"]
        # contains the Binding for the 'company,dev' device, when it
        # appears on the CAN bus.
        #
        # For bindings that don't specify a bus, <bus> is None, so that e.g.
        # self._compat2binding["company,notonbus", None] is the Binding.
        #
        # Only bindings for 'compatible' strings that appear in the devicetree
        # are loaded.

        dt_compats = _dt_compats(self._dt)
        # Searches for any 'compatible' string mentioned in the devicetree
        # files, with a regex
        dt_compats_search = re.compile(
            "|".join(re.escape(compat) for compat in dt_compats)
        ).search

        self._binding_paths = _binding_paths(self.bindings_dirs)
        self._binding_fname2path = {os.path.basename(path): path
                                    for path in self._binding_paths}

        self._compat2binding = {}
        for binding_path in self._binding_paths:
            with open(binding_path, encoding="utf-8") as f:
                contents = f.read()

            # As an optimization, skip parsing files that don't contain any of
            # the .dts 'compatible' strings, which should be reasonably safe
            if not dt_compats_search(contents):
                continue

            # Load the binding and check that it actually matches one of the
            # compatibles. Might get false positives above due to comments and
            # stuff.

            try:
                # Parsed PyYAML output (Python lists/dictionaries/strings/etc.,
                # representing the file)
                raw = yaml.load(contents, Loader=_BindingLoader)
            except yaml.YAMLError as e:
                _err(
                        f"'{binding_path}' appears in binding directories "
                        f"but isn't valid YAML: {e}")
                continue

            # Convert the raw data to a Binding object, erroring out
            # if necessary.
            binding = self._binding(raw, binding_path, dt_compats)

            # Register the binding in self._compat2binding, along with
            # any child bindings that have their own compatibles.
            while binding is not None:
                if binding.compatible:
                    self._register_binding(binding)
                binding = binding.child_binding

    def _binding(self, raw, binding_path, dt_compats):
        # Convert a 'raw' binding from YAML to a Binding object and return it.
        #
        # Error out if the raw data looks like an invalid binding.
        #
        # Return None if the file doesn't contain a binding or the
        # binding's compatible isn't in dt_compats.

        # Get the 'compatible:' string.
        if raw is None or "compatible" not in raw:
            # Empty file, binding fragment, spurious file, etc.
            return None

        compatible = raw["compatible"]

        if compatible not in dt_compats:
            # Not a compatible we care about.
            return None

        # Initialize and return the Binding object.
        return Binding(binding_path, self._binding_fname2path, raw=raw)

    def _register_binding(self, binding):
        # Do not allow two different bindings to have the same
        # 'compatible:'/'on-bus:' combo
        old_binding = self._compat2binding.get((binding.compatible,
                                                binding.on_bus))
        if old_binding:
            msg = (f"both {old_binding.path} and {binding.path} have "
                   f"'compatible: {binding.compatible}'")
            if binding.on_bus is not None:
                msg += f" and 'on-bus: {binding.on_bus}'"
            _err(msg)

        # Register the binding.
        self._compat2binding[binding.compatible, binding.on_bus] = binding

    def _init_nodes(self):
        # Creates a list of edtlib.Node objects from the dtlib.Node objects, in
        # self.nodes

        # Maps each dtlib.Node to its corresponding edtlib.Node
        self._node2enode = {}

        self.nodes = []

        for dt_node in self._dt.node_iter():
            # Warning: We depend on parent Nodes being created before their
            # children. This is guaranteed by node_iter().
            node = Node()
            node.edt = self
            node._node = dt_node
            if "compatible" in node._node.props:
                node.compats = node._node.props["compatible"].to_strings()
            else:
                node.compats = []
            node.bus_node = node._bus_node(self._fixed_partitions_no_bus)
            node._init_binding()
            node._init_regs()
            node._init_ranges()

            self.nodes.append(node)
            self._node2enode[dt_node] = node

        for node in self.nodes:
            # These depend on all Node objects having been created, because
            # they (either always or sometimes) reference other nodes, so we
            # run them separately
            node._init_props(default_prop_types=self._default_prop_types,
                             err_on_deprecated=self._werror)
            node._init_interrupts()
            node._init_pinctrls()

        if self._warn_reg_unit_address_mismatch:
            # This warning matches the simple_bus_reg warning in dtc
            for node in self.nodes:
                if node.regs and node.regs[0].addr != node.unit_addr:
                    _LOG.warning("unit address and first address in 'reg' "
                                 f"(0x{node.regs[0].addr:x}) don't match for "
                                 f"{node.path}")

    def _init_luts(self):
        # Initialize node lookup tables (LUTs).

        self.label2node = OrderedDict()
        self.dep_ord2node = OrderedDict()
        self.compat2nodes = defaultdict(list)
        self.compat2okay = defaultdict(list)
        self.compat2vendor = defaultdict(str)

        for node in self.nodes:
            for label in node.labels:
                self.label2node[label] = node

            for compat in node.compats:
                self.compat2nodes[compat].append(node)

                if node.status == "okay":
                    self.compat2okay[compat].append(node)

                if compat in self.compat2vendor:
                    continue

                # The regular expression comes from dt-schema.
                compat_re = r'^[a-zA-Z][a-zA-Z0-9,+\-._]+$'
                if not re.match(compat_re, compat):
                    _err(f"node '{node.path}' compatible '{compat}' "
                         'must match this regular expression: '
                         f"'{compat_re}'")

                if ',' in compat and self._vendor_prefixes:
                    vendor = compat.split(',', 1)[0]
                    if vendor in self._vendor_prefixes:
                        self.compat2vendor[compat] = self._vendor_prefixes[vendor]

                    # As an exception, the root node can have whatever
                    # compatibles it wants. Other nodes get checked.
                    elif node.path != '/' and \
                       vendor not in _VENDOR_PREFIX_ALLOWED:
                        if self._werror:
                            handler_fn = _err
                        else:
                            handler_fn = _LOG.warning
                        handler_fn(
                            f"node '{node.path}' compatible '{compat}' "
                            f"has unknown vendor prefix '{vendor}'")


        for nodeset in self.scc_order:
            node = nodeset[0]
            self.dep_ord2node[node.dep_ordinal] = node

    def _check(self):
        # Tree-wide checks and warnings.

        for binding in self._compat2binding.values():
            for spec in binding.prop2specs.values():
                if not spec.enum or spec.type != 'string':
                    continue

                if not spec.enum_tokenizable:
                    _LOG.warning(
                        f"compatible '{binding.compatible}' "
                        f"in binding '{binding.path}' has non-tokenizable enum "
                        f"for property '{spec.name}': " +
                        ', '.join(repr(x) for x in spec.enum))
                elif not spec.enum_upper_tokenizable:
                    _LOG.warning(
                        f"compatible '{binding.compatible}' "
                        f"in binding '{binding.path}' has enum for property "
                        f"'{spec.name}' that is only tokenizable "
                        'in lowercase: ' +
                        ', '.join(repr(x) for x in spec.enum))

        # Validate the contents of compatible properties.
        for node in self.nodes:
            if 'compatible' not in node.props:
                continue

            compatibles = node.props['compatible'].val

            # _check() runs after _init_compat2binding() has called
            # _dt_compats(), which already converted every compatible
            # property to a list of strings. So we know 'compatibles'
            # is a list, but add an assert for future-proofing.
            assert isinstance(compatibles, list)

            for compat in compatibles:
                # This is also just for future-proofing.
                assert isinstance(compat, str)


class Node:
    """
    Represents a devicetree node, augmented with information from bindings, and
    with some interpretation of devicetree properties. There's a one-to-one
    correspondence between devicetree nodes and Nodes.

    These attributes are available on Node objects:

    edt:
      The EDT instance this node is from

    name:
      The name of the node

    unit_addr:
      An integer with the ...@<unit-address> portion of the node name,
      translated through any 'ranges' properties on parent nodes, or None if
      the node name has no unit-address portion

    description:
      The description string from the binding for the node, or None if the node
      has no binding. Leading and trailing whitespace (including newlines) is
      removed.

    path:
      The devicetree path of the node

    label:
      The text from the 'label' property on the node, or None if the node has
      no 'label'

    labels:
      A list of all of the devicetree labels for the node, in the same order
      as the labels appear, but with duplicates removed.

      This corresponds to the actual devicetree source labels, unlike the
      "label" attribute, which is the value of a devicetree property named
      "label".

    parent:
      The Node instance for the devicetree parent of the Node, or None if the
      node is the root node

    children:
      A dictionary with the Node instances for the devicetree children of the
      node, indexed by name

    dep_ordinal:
      A non-negative integer value such that the value for a Node is
      less than the value for all Nodes that depend on it.

      The ordinal is defined for all Nodes, and is unique among nodes in its
      EDT 'nodes' list.

    required_by:
      A list with the nodes that directly depend on the node

    depends_on:
      A list with the nodes that the node directly depends on

    status:
      The node's status property value, as a string, or "okay" if the node
      has no status property set. If the node's status property is "ok",
      it is converted to "okay" for consistency.

    read_only:
      True if the node has a 'read-only' property, and False otherwise

    matching_compat:
      The 'compatible' string for the binding that matched the node, or None if
      the node has no binding

    binding_path:
      The path to the binding file for the node, or None if the node has no
      binding

    compats:
      A list of 'compatible' strings for the node, in the same order that
      they're listed in the .dts file

    ranges:
      A list if Range objects extracted from the node's ranges property.
      The list is empty if the node does not have a range property.

    regs:
      A list of Register objects for the node's registers

    props:
      A collections.OrderedDict that maps property names to Property objects.
      Property objects are created for all devicetree properties on the node
      that are mentioned in 'properties:' in the binding.

    aliases:
      A list of aliases for the node. This is fetched from the /aliases node.

    interrupts:
      A list of ControllerAndData objects for the interrupts generated by the
      node. The list is empty if the node does not generate interrupts.

    pinctrls:
      A list of PinCtrl objects for the pinctrl-<index> properties on the
      node, sorted by index. The list is empty if the node does not have any
      pinctrl-<index> properties.

    buses:
      If the node is a bus node (has a 'bus:' key in its binding), then this
      attribute holds the list of supported bus types, e.g. ["i2c"], ["spi"]
      or ["i3c", "i2c"] if multiple protocols are supported via the same bus.
      If the node is not a bus node, then this attribute is an empty list.

    on_buses:
      The bus the node appears on, e.g. ["i2c"], ["spi"] or ["i3c", "i2c"] if
      multiple protocols are supported via the same bus. The bus is determined
      by searching upwards for a parent node whose binding has a 'bus:' key,
      returning the value of the first 'bus:' key found. If none of the node's
      parents has a 'bus:' key, this attribute is an empty list.

    bus_node:
      Like on_bus, but contains the Node for the bus controller, or None if the
      node is not on a bus.

    flash_controller:
      The flash controller for the node. Only meaningful for nodes representing
      flash partitions.

    spi_cs_gpio:
      The device's SPI GPIO chip select as a ControllerAndData instance, if it
      exists, and None otherwise. See
      Documentation/devicetree/bindings/spi/spi-controller.yaml in the Linux kernel.
    """
    @property
    def name(self):
        "See the class docstring"
        return self._node.name

    @property
    def unit_addr(self):
        "See the class docstring"

        # TODO: Return a plain string here later, like dtlib.Node.unit_addr?

        if "@" not in self.name:
            return None

        try:
            addr = int(self.name.split("@", 1)[1], 16)
        except ValueError:
            _err(f"{self!r} has non-hex unit address")

        return _translate(addr, self._node)

    @property
    def description(self):
        "See the class docstring."
        if self._binding:
            return self._binding.description
        return None

    @property
    def path(self):
        "See the class docstring"
        return self._node.path

    @property
    def label(self):
        "See the class docstring"
        if "label" in self._node.props:
            return self._node.props["label"].to_string()
        return None

    @property
    def labels(self):
        "See the class docstring"
        return self._node.labels

    @property
    def parent(self):
        "See the class docstring"
        return self.edt._node2enode.get(self._node.parent)

    @property
    def children(self):
        "See the class docstring"
        # Could be initialized statically too to preserve identity, but not
        # sure if needed. Parent nodes being initialized before their children
        # would need to be kept in mind.
        return OrderedDict((name, self.edt._node2enode[node])
                           for name, node in self._node.nodes.items())

    def child_index(self, node):
        """Get the index of *node* in self.children.
        Raises KeyError if the argument is not a child of this node.
        """
        if not hasattr(self, '_child2index'):
            # Defer initialization of this lookup table until this
            # method is callable to handle parents needing to be
            # initialized before their chidlren. By the time we
            # return from __init__, 'self.children' is callable.
            self._child2index = OrderedDict()
            for index, child in enumerate(self.children.values()):
                self._child2index[child] = index

        return self._child2index[node]

    @property
    def required_by(self):
        "See the class docstring"
        return self.edt._graph.required_by(self)

    @property
    def depends_on(self):
        "See the class docstring"
        return self.edt._graph.depends_on(self)

    @property
    def status(self):
        "See the class docstring"
        status = self._node.props.get("status")

        if status is None:
            as_string = "okay"
        else:
            as_string = status.to_string()

        if as_string == "ok":
            as_string = "okay"

        return as_string

    @property
    def read_only(self):
        "See the class docstring"
        return "read-only" in self._node.props

    @property
    def aliases(self):
        "See the class docstring"
        return [alias for alias, node in self._node.dt.alias2node.items()
                if node is self._node]

    @property
    def buses(self):
        "See the class docstring"
        if self._binding:
            return self._binding.buses
        return []

    @property
    def on_buses(self):
        "See the class docstring"
        bus_node = self.bus_node
        return bus_node.buses if bus_node else []

    @property
    def flash_controller(self):
        "See the class docstring"

        # The node path might be something like
        # /flash-controller@4001E000/flash@0/partitions/partition@fc000. We go
        # up two levels to get the flash and check its compat. The flash
        # controller might be the flash itself (for cases like NOR flashes).
        # For the case of 'soc-nv-flash', we assume the controller is the
        # parent of the flash node.

        if not self.parent or not self.parent.parent:
            _err(f"flash partition {self!r} lacks parent or grandparent node")

        controller = self.parent.parent
        if controller.matching_compat == "soc-nv-flash":
            return controller.parent
        return controller

    @property
    def spi_cs_gpio(self):
        "See the class docstring"

        # We know on_buses is always a list, but pylint doesn't.
        # So ignore the error.
        if not ("spi" in self.on_buses # pylint: disable=unsupported-membership-test
                and "cs-gpios" in self.bus_node.props):
            return None

        if not self.regs:
            _err(f"{self!r} needs a 'reg' property, to look up the "
                 "chip select index for SPI")

        parent_cs_lst = self.bus_node.props["cs-gpios"].val

        # cs-gpios is indexed by the unit address
        cs_index = self.regs[0].addr
        if cs_index >= len(parent_cs_lst):
            _err(f"index from 'regs' in {self!r} ({cs_index}) "
                 "is >= number of cs-gpios in "
                 f"{self.bus_node!r} ({len(parent_cs_lst)})")

        return parent_cs_lst[cs_index]

    def __repr__(self):
        if self.binding_path:
            binding = "binding " + self.binding_path
        else:
            binding = "no binding"
        return f"<Node {self.path} in '{self.edt.dts_path}', {binding}>"

    def _init_binding(self):
        # Initializes Node.matching_compat, Node._binding, and
        # Node.binding_path.
        #
        # Node._binding holds the data from the node's binding file, in the
        # format returned by PyYAML (plain Python lists, dicts, etc.), or None
        # if the node has no binding.

        # This relies on the parent of the node having already been
        # initialized, which is guaranteed by going through the nodes in
        # node_iter() order.

        if self.path in self.edt._infer_binding_for_paths:
            self._binding_from_properties()
            return

        if self.compats:
            on_buses = self.on_buses

            for compat in self.compats:
                # When matching, respect the order of the 'compatible' entries,
                # and for each one first try to match against an explicitly
                # specified bus (if any) and then against any bus. This is so
                # that matching against bindings which do not specify a bus
                # works the same way in Zephyr as it does elsewhere.
                binding = None

                # We know on_buses is always a list, but pylint doesn't.
                # So ignore the error.
                for bus in on_buses: # pylint: disable=not-an-iterable
                    if (compat, bus) in self.edt._compat2binding:
                        binding = self.edt._compat2binding[compat, bus]
                        break

                if not binding:
                    if (compat, None) in self.edt._compat2binding:
                        binding = self.edt._compat2binding[compat, None]
                    else:
                        continue

                self.binding_path = binding.path
                self.matching_compat = compat
                self._binding = binding
                return
        else:
            # No 'compatible' property. See if the parent binding has
            # a compatible. This can come from one or more levels of
            # nesting with 'child-binding:'.

            binding_from_parent = self._binding_from_parent()
            if binding_from_parent:
                self._binding = binding_from_parent
                self.binding_path = self._binding.path
                self.matching_compat = self._binding.compatible

                return

        # No binding found
        self._binding = self.binding_path = self.matching_compat = None

    def _binding_from_properties(self):
        # Sets up a Binding object synthesized from the properties in the node.

        if self.compats:
            _err(f"compatible in node with inferred binding: {self.path}")

        # Synthesize a 'raw' binding as if it had been parsed from YAML.
        raw = {
            'description': 'Inferred binding from properties, via edtlib.',
            'properties': {},
        }
        for name, prop in self._node.props.items():
            pp = OrderedDict()
            if prop.type == Type.EMPTY:
                pp["type"] = "boolean"
            elif prop.type == Type.BYTES:
                pp["type"] = "uint8-array"
            elif prop.type == Type.NUM:
                pp["type"] = "int"
            elif prop.type == Type.NUMS:
                pp["type"] = "array"
            elif prop.type == Type.STRING:
                pp["type"] = "string"
            elif prop.type == Type.STRINGS:
                pp["type"] = "string-array"
            elif prop.type == Type.PHANDLE:
                pp["type"] = "phandle"
            elif prop.type == Type.PHANDLES:
                pp["type"] = "phandles"
            elif prop.type == Type.PHANDLES_AND_NUMS:
                pp["type"] = "phandle-array"
            elif prop.type == Type.PATH:
                pp["type"] = "path"
            else:
                _err(f"cannot infer binding from property: {prop} "
                     f"with type {prop.type!r}")
            raw['properties'][name] = pp

        # Set up Node state.
        self.binding_path = None
        self.matching_compat = None
        self.compats = []
        self._binding = Binding(None, {}, raw=raw, require_compatible=False)

    def _binding_from_parent(self):
        # Returns the binding from 'child-binding:' in the parent node's
        # binding.

        if not self.parent:
            return None

        pbinding = self.parent._binding
        if not pbinding:
            return None

        if pbinding.child_binding:
            return pbinding.child_binding

        return None

    def _bus_node(self, support_fixed_partitions_on_any_bus = True):
        # Returns the value for self.bus_node. Relies on parent nodes being
        # initialized before their children.

        if not self.parent:
            # This is the root node
            return None

        # Treat 'fixed-partitions' as if they are not on any bus.  The reason is
        # that flash nodes might be on a SPI or controller or SoC bus.  Having
        # bus be None means we'll always match the binding for fixed-partitions
        # also this means want processing the fixed-partitions node we wouldn't
        # try to do anything bus specific with it.
        if support_fixed_partitions_on_any_bus and "fixed-partitions" in self.compats:
            return None

        if self.parent.buses:
            # The parent node is a bus node
            return self.parent

        # Same bus node as parent (possibly None)
        return self.parent.bus_node

    def _init_props(self, default_prop_types=False, err_on_deprecated=False):
        # Creates self.props. See the class docstring. Also checks that all
        # properties on the node are declared in its binding.

        self.props = OrderedDict()

        node = self._node
        if self._binding:
            prop2specs = self._binding.prop2specs
        else:
            prop2specs = None

        # Initialize self.props
        if prop2specs:
            for prop_spec in prop2specs.values():
                self._init_prop(prop_spec, err_on_deprecated)
            self._check_undeclared_props()
        elif default_prop_types:
            for name in node.props:
                if name not in _DEFAULT_PROP_SPECS:
                    continue
                prop_spec = _DEFAULT_PROP_SPECS[name]
                val = self._prop_val(name, prop_spec.type, False, False, None,
                                     None, err_on_deprecated)
                self.props[name] = Property(prop_spec, val, self)

    def _init_prop(self, prop_spec, err_on_deprecated):
        # _init_props() helper for initializing a single property.
        # 'prop_spec' is a PropertySpec object from the node's binding.

        name = prop_spec.name
        prop_type = prop_spec.type
        if not prop_type:
            _err(f"'{name}' in {self.binding_path} lacks 'type'")

        val = self._prop_val(name, prop_type, prop_spec.deprecated,
                             prop_spec.required, prop_spec.default,
                             prop_spec.specifier_space, err_on_deprecated)

        if val is None:
            # 'required: false' property that wasn't there, or a property type
            # for which we store no data.
            return

        enum = prop_spec.enum
        if enum and val not in enum:
            _err(f"value of property '{name}' on {self.path} in "
                 f"{self.edt.dts_path} ({val!r}) is not in 'enum' list in "
                 f"{self.binding_path} ({enum!r})")

        const = prop_spec.const
        if const is not None and val != const:
            _err(f"value of property '{name}' on {self.path} in "
                 f"{self.edt.dts_path} ({val!r}) "
                 "is different from the 'const' value specified in "
                 f"{self.binding_path} ({const!r})")

        # Skip properties that start with '#', like '#size-cells', and mapping
        # properties like 'gpio-map'/'interrupt-map'
        if name[0] == "#" or name.endswith("-map"):
            return

        self.props[name] = Property(prop_spec, val, self)

    def _prop_val(self, name, prop_type, deprecated, required, default,
                  specifier_space, err_on_deprecated):
        # _init_prop() helper for getting the property's value
        #
        # name:
        #   Property name from binding
        #
        # prop_type:
        #   Property type from binding (a string like "int")
        #
        # deprecated:
        #   True if the property is deprecated
        #
        # required:
        #   True if the property is required to exist
        #
        # default:
        #   Default value to use when the property doesn't exist, or None if
        #   the binding doesn't give a default value
        #
        # specifier_space:
        #   Property specifier-space from binding (if prop_type is "phandle-array")
        #
        # err_on_deprecated:
        #   If True, a deprecated property is an error instead of warning.

        node = self._node
        prop = node.props.get(name)

        if prop and deprecated:
            msg = (f"'{name}' is marked as deprecated in 'properties:' "
                   f"in {self.binding_path} for node {node.path}.")
            if err_on_deprecated:
                _err(msg)
            else:
                _LOG.warning(msg)

        if not prop:
            if required and self.status == "okay":
                _err(f"'{name}' is marked as required in 'properties:' in "
                     f"{self.binding_path}, but does not appear in {node!r}")

            if default is not None:
                # YAML doesn't have a native format for byte arrays. We need to
                # convert those from an array like [0x12, 0x34, ...]. The
                # format has already been checked in
                # _check_prop_by_type().
                if prop_type == "uint8-array":
                    return bytes(default)
                return default

            return False if prop_type == "boolean" else None

        if prop_type == "boolean":
            if prop.type != Type.EMPTY:
                _err("'{0}' in {1!r} is defined with 'type: boolean' in {2}, "
                     "but is assigned a value ('{3}') instead of being empty "
                     "('{0};')".format(name, node, self.binding_path, prop))
            return True

        if prop_type == "int":
            return prop.to_num()

        if prop_type == "array":
            return prop.to_nums()

        if prop_type == "uint8-array":
            return prop.to_bytes()

        if prop_type == "string":
            return prop.to_string()

        if prop_type == "string-array":
            return prop.to_strings()

        if prop_type == "phandle":
            return self.edt._node2enode[prop.to_node()]

        if prop_type == "phandles":
            return [self.edt._node2enode[node] for node in prop.to_nodes()]

        if prop_type == "phandle-array":
            # This type is a bit high-level for dtlib as it involves
            # information from bindings and *-names properties, so there's no
            # to_phandle_array() in dtlib. Do the type check ourselves.
            if prop.type not in (Type.PHANDLE, Type.PHANDLES, Type.PHANDLES_AND_NUMS):
                _err(f"expected property '{name}' in {node.path} in "
                     f"{node.dt.filename} to be assigned "
                     f"with '{name} = < &foo ... &bar 1 ... &baz 2 3 >' "
                     f"(a mix of phandles and numbers), not '{prop}'")

            return self._standard_phandle_val_list(prop, specifier_space)

        if prop_type == "path":
            return self.edt._node2enode[prop.to_path()]

        # prop_type == "compound". Checking that the 'type:'
        # value is valid is done in _check_prop_by_type().
        #
        # 'compound' is a dummy type for properties that don't fit any of the
        # patterns above, so that we can require all entries in 'properties:'
        # to have a 'type: ...'. No Property object is created for it.
        return None

    def _check_undeclared_props(self):
        # Checks that all properties are declared in the binding

        for prop_name in self._node.props:
            # Allow a few special properties to not be declared in the binding
            if prop_name.endswith("-controller") or \
               prop_name.startswith("#") or \
               prop_name.startswith("pinctrl-") or \
               prop_name in {
                   "compatible", "status", "ranges", "phandle",
                   "interrupt-parent", "interrupts-extended", "device_type"}:
                continue

            if prop_name not in self._binding.prop2specs:
                _err(f"'{prop_name}' appears in {self._node.path} in "
                     f"{self.edt.dts_path}, but is not declared in "
                     f"'properties:' in {self.binding_path}")

    def _init_ranges(self):
        # Initializes self.ranges
        node = self._node

        self.ranges = []

        if "ranges" not in node.props:
            return

        child_address_cells = node.props.get("#address-cells")
        parent_address_cells = _address_cells(node)
        if child_address_cells is None:
            child_address_cells = 2 # Default value per DT spec.
        else:
            child_address_cells = child_address_cells.to_num()
        child_size_cells = node.props.get("#size-cells")
        if child_size_cells is None:
            child_size_cells = 1 # Default value per DT spec.
        else:
            child_size_cells = child_size_cells.to_num()

        # Number of cells for one translation 3-tuple in 'ranges'
        entry_cells = child_address_cells + parent_address_cells + child_size_cells

        if entry_cells == 0:
            if len(node.props["ranges"].value) == 0:
                return
            else:
                _err(f"'ranges' should be empty in {self._node.path} since "
                     f"<#address-cells> = {child_address_cells}, "
                     f"<#address-cells for parent> = {parent_address_cells} and "
                     f"<#size-cells> = {child_size_cells}")

        for raw_range in _slice(node, "ranges", 4*entry_cells,
                                f"4*(<#address-cells> (= {child_address_cells}) + "
                                "<#address-cells for parent> "
                                f"(= {parent_address_cells}) + "
                                f"<#size-cells> (= {child_size_cells}))"):

            range = Range()
            range.node = self
            range.child_bus_cells = child_address_cells
            if child_address_cells == 0:
                range.child_bus_addr = None
            else:
                range.child_bus_addr = to_num(raw_range[:4*child_address_cells])
            range.parent_bus_cells = parent_address_cells
            if parent_address_cells == 0:
                range.parent_bus_addr = None
            else:
                range.parent_bus_addr = to_num(raw_range[(4*child_address_cells):\
                                            (4*child_address_cells + 4*parent_address_cells)])
            range.length_cells = child_size_cells
            if child_size_cells == 0:
                range.length = None
            else:
                range.length = to_num(raw_range[(4*child_address_cells + \
                                                    4*parent_address_cells):])

            self.ranges.append(range)

    def _init_regs(self):
        # Initializes self.regs

        node = self._node

        self.regs = []

        if "reg" not in node.props:
            return

        address_cells = _address_cells(node)
        size_cells = _size_cells(node)

        for raw_reg in _slice(node, "reg", 4*(address_cells + size_cells),
                              f"4*(<#address-cells> (= {address_cells}) + "
                              f"<#size-cells> (= {size_cells}))"):
            reg = Register()
            reg.node = self
            if address_cells == 0:
                reg.addr = None
            else:
                reg.addr = _translate(to_num(raw_reg[:4*address_cells]), node)
            if size_cells == 0:
                reg.size = None
            else:
                reg.size = to_num(raw_reg[4*address_cells:])
            if size_cells != 0 and reg.size == 0:
                _err(f"zero-sized 'reg' in {self._node!r} seems meaningless "
                     "(maybe you want a size of one or #size-cells = 0 "
                     "instead)")

            self.regs.append(reg)

        _add_names(node, "reg", self.regs)

    def _init_pinctrls(self):
        # Initializes self.pinctrls from any pinctrl-<index> properties

        node = self._node

        # pinctrl-<index> properties
        pinctrl_props = [prop for name, prop in node.props.items()
                         if re.match("pinctrl-[0-9]+", name)]
        # Sort by index
        pinctrl_props.sort(key=lambda prop: prop.name)

        # Check indices
        for i, prop in enumerate(pinctrl_props):
            if prop.name != "pinctrl-" + str(i):
                _err(f"missing 'pinctrl-{i}' property on {node!r} "
                     "- indices should be contiguous and start from zero")

        self.pinctrls = []
        for prop in pinctrl_props:
            pinctrl = PinCtrl()
            pinctrl.node = self
            pinctrl.conf_nodes = [
                self.edt._node2enode[node] for node in prop.to_nodes()
            ]
            self.pinctrls.append(pinctrl)

        _add_names(node, "pinctrl", self.pinctrls)

    def _init_interrupts(self):
        # Initializes self.interrupts

        node = self._node

        self.interrupts = []

        for controller_node, data in _interrupts(node):
            interrupt = ControllerAndData()
            interrupt.node = self
            interrupt.controller = self.edt._node2enode[controller_node]
            interrupt.data = self._named_cells(interrupt.controller, data,
                                               "interrupt")

            self.interrupts.append(interrupt)

        _add_names(node, "interrupt", self.interrupts)

    def _standard_phandle_val_list(self, prop, specifier_space):
        # Parses a property like
        #
        #     <prop.name> = <phandle cell phandle cell ...>;
        #
        # where each phandle points to a controller node that has a
        #
        #     #<specifier_space>-cells = <size>;
        #
        # property that gives the number of cells in the value after the
        # controller's phandle in the property.
        #
        # E.g. with a property like
        #
        #     pwms = <&foo 1 2 &bar 3>;
        #
        # If 'specifier_space' is "pwm", then we should have this elsewhere
        # in the tree:
        #
        #     foo: ... {
        #             #pwm-cells = <2>;
        #     };
        #
        #     bar: ... {
        #             #pwm-cells = <1>;
        #     };
        #
        # These values can be given names using the <specifier_space>-names:
        # list in the binding for the phandle nodes.
        #
        # Also parses any
        #
        #     <specifier_space>-names = "...", "...", ...
        #
        # Returns a list of Optional[ControllerAndData] instances.
        #
        # An index is None if the underlying phandle-array element is
        # unspecified.

        if not specifier_space:
            if prop.name.endswith("gpios"):
                # There's some slight special-casing for *-gpios properties in that
                # e.g. foo-gpios still maps to #gpio-cells rather than
                # #foo-gpio-cells
                specifier_space = "gpio"
            else:
                # Strip -s. We've already checked that property names end in -s
                # if there is no specifier space in _check_prop_by_type().
                specifier_space = prop.name[:-1]

        res = []

        for item in _phandle_val_list(prop, specifier_space):
            if item is None:
                res.append(None)
                continue

            controller_node, data = item
            mapped_controller, mapped_data = \
                _map_phandle_array_entry(prop.node, controller_node, data,
                                         specifier_space)

            entry = ControllerAndData()
            entry.node = self
            entry.controller = self.edt._node2enode[mapped_controller]
            entry.basename = specifier_space
            entry.data = self._named_cells(entry.controller, mapped_data,
                                           specifier_space)

            res.append(entry)

        _add_names(self._node, specifier_space, res)

        return res

    def _named_cells(self, controller, data, basename):
        # Returns a dictionary that maps <basename>-cells names given in the
        # binding for 'controller' to cell values. 'data' is the raw data, as a
        # byte array.

        if not controller._binding:
            _err(f"{basename} controller {controller._node!r} "
                 f"for {self._node!r} lacks binding")

        if basename in controller._binding.specifier2cells:
            cell_names = controller._binding.specifier2cells[basename]
        else:
            # Treat no *-cells in the binding the same as an empty *-cells, so
            # that bindings don't have to have e.g. an empty 'clock-cells:' for
            # '#clock-cells = <0>'.
            cell_names = []

        data_list = to_nums(data)
        if len(data_list) != len(cell_names):
            _err(f"unexpected '{basename}-cells:' length in binding for "
                 f"{controller._node!r} - {len(cell_names)} "
                 f"instead of {len(data_list)}")

        return OrderedDict(zip(cell_names, data_list))


class Range:
    """
    Represents a translation range on a node as described by the 'ranges' property.

    These attributes are available on Range objects:

    node:
      The Node instance this range is from

    child_bus_cells:
      Is the number of cells (4-bytes wide words) describing the child bus address.

    child_bus_addr:
      Is a physical address within the child bus address space, or None if the
      child address-cells is equal 0.

    parent_bus_cells:
      Is the number of cells (4-bytes wide words) describing the parent bus address.

    parent_bus_addr:
      Is a physical address within the parent bus address space, or None if the
      parent address-cells is equal 0.

    length_cells:
      Is the number of cells (4-bytes wide words) describing the size of range in
      the child address space.

    length:
      Specifies the size of the range in the child address space, or None if the
      child size-cells is equal 0.
    """
    def __repr__(self):
        fields = []

        if self.child_bus_cells is not None:
            fields.append("child-bus-cells: " + hex(self.child_bus_cells))
        if self.child_bus_addr is not None:
            fields.append("child-bus-addr: " + hex(self.child_bus_addr))
        if self.parent_bus_cells is not None:
            fields.append("parent-bus-cells: " + hex(self.parent_bus_cells))
        if self.parent_bus_addr is not None:
            fields.append("parent-bus-addr: " + hex(self.parent_bus_addr))
        if self.length_cells is not None:
            fields.append("length-cells " + hex(self.length_cells))
        if self.length is not None:
            fields.append("length " + hex(self.length))

        return "<Range, {}>".format(", ".join(fields))

class Register:
    """
    Represents a register on a node.

    These attributes are available on Register objects:

    node:
      The Node instance this register is from

    name:
      The name of the register as given in the 'reg-names' property, or None if
      there is no 'reg-names' property

    addr:
      The starting address of the register, in the parent address space, or None
      if #address-cells is zero. Any 'ranges' properties are taken into account.

    size:
      The length of the register in bytes
    """
    def __repr__(self):
        fields = []

        if self.name is not None:
            fields.append("name: " + self.name)
        if self.addr is not None:
            fields.append("addr: " + hex(self.addr))
        if self.size is not None:
            fields.append("size: " + hex(self.size))

        return "<Register, {}>".format(", ".join(fields))


class ControllerAndData:
    """
    Represents an entry in an 'interrupts' or 'type: phandle-array' property
    value, e.g. <&ctrl-1 4 0> in

        cs-gpios = <&ctrl-1 4 0 &ctrl-2 3 4>;

    These attributes are available on ControllerAndData objects:

    node:
      The Node instance the property appears on

    controller:
      The Node instance for the controller (e.g. the controller the interrupt
      gets sent to for interrupts)

    data:
      A dictionary that maps names from the *-cells key in the binding for the
      controller to data values, e.g. {"pin": 4, "flags": 0} for the example
      above.

      'interrupts = <1 2>' might give {"irq": 1, "level": 2}.

    name:
      The name of the entry as given in
      'interrupt-names'/'gpio-names'/'pwm-names'/etc., or None if there is no
      *-names property

    basename:
      Basename for the controller when supporting named cells
    """
    def __repr__(self):
        fields = []

        if self.name is not None:
            fields.append("name: " + self.name)

        fields.append(f"controller: {self.controller}")
        fields.append(f"data: {self.data}")

        return "<ControllerAndData, {}>".format(", ".join(fields))


class PinCtrl:
    """
    Represents a pin control configuration for a set of pins on a device,
    e.g. pinctrl-0 or pinctrl-1.

    These attributes are available on PinCtrl objects:

    node:
      The Node instance the pinctrl-* property is on

    name:
      The name of the configuration, as given in pinctrl-names, or None if
      there is no pinctrl-names property

    name_as_token:
      Like 'name', but with non-alphanumeric characters converted to underscores.

    conf_nodes:
      A list of Node instances for the pin configuration nodes, e.g.
      the nodes pointed at by &state_1 and &state_2 in

          pinctrl-0 = <&state_1 &state_2>;
    """

    @property
    def name_as_token(self):
        "See the class docstring"
        return str_as_token(self.name) if self.name is not None else None

    def __repr__(self):
        fields = []

        if self.name is not None:
            fields.append("name: " + self.name)

        fields.append("configuration nodes: " + str(self.conf_nodes))

        return "<PinCtrl, {}>".format(", ".join(fields))


class Property:
    """
    Represents a property on a Node, as set in its DT node and with
    additional info from the 'properties:' section of the binding.

    Only properties mentioned in 'properties:' get created. Properties of type
    'compound' currently do not get Property instances, as it's not clear
    what to generate for them.

    These attributes are available on Property objects. Several are
    just convenience accessors for attributes on the PropertySpec object
    accessible via the 'spec' attribute.

    These attributes are available on Property objects:

    node:
      The Node instance the property is on

    spec:
      The PropertySpec object which specifies this property.

    name:
      Convenience for spec.name.

    description:
      Convenience for spec.name with leading and trailing whitespace
      (including newlines) removed.

    type:
      Convenience for spec.type.

    val:
      The value of the property, with the format determined by spec.type,
      which comes from the 'type:' string in the binding.

        - For 'type: int/array/string/string-array', 'val' is what you'd expect
          (a Python integer or string, or a list of them)

        - For 'type: phandle' and 'type: path', 'val' is the pointed-to Node
          instance

        - For 'type: phandles', 'val' is a list of the pointed-to Node
          instances

        - For 'type: phandle-array', 'val' is a list of ControllerAndData
          instances. See the documentation for that class.

    val_as_token:
      The value of the property as a token, i.e. with non-alphanumeric
      characters replaced with underscores. This is only safe to access
      if self.enum_tokenizable returns True.

    enum_index:
      The index of 'val' in 'spec.enum' (which comes from the 'enum:' list
      in the binding), or None if spec.enum is None.
    """

    def __init__(self, spec, val, node):
        self.val = val
        self.spec = spec
        self.node = node

    @property
    def name(self):
        "See the class docstring"
        return self.spec.name

    @property
    def description(self):
        "See the class docstring"
        return self.spec.description.strip()

    @property
    def type(self):
        "See the class docstring"
        return self.spec.type

    @property
    def val_as_token(self):
        "See the class docstring"
        return str_as_token(self.val)

    @property
    def enum_index(self):
        "See the class docstring"
        enum = self.spec.enum
        return enum.index(self.val) if enum else None

    def __repr__(self):
        fields = ["name: " + self.name,
                  # repr() to deal with lists
                  "type: " + self.type,
                  "value: " + repr(self.val)]

        if self.enum_index is not None:
            fields.append(f"enum index: {self.enum_index}")

        return "<Property, {}>".format(", ".join(fields))


class Binding:
    """
    Represents a parsed binding.

    These attributes are available on Binding objects:

    path:
      The absolute path to the file defining the binding.

    description:
      The free-form description of the binding.

    compatible:
      The compatible string the binding matches.

      This may be None. For example, it's None when the Binding is inferred
      from node properties. It can also be None for Binding objects created
      using 'child-binding:' with no compatible.

    prop2specs:
      A collections.OrderedDict mapping property names to PropertySpec objects
      describing those properties' values.

    specifier2cells:
      A collections.OrderedDict that maps specifier space names (like "gpio",
      "clock", "pwm", etc.) to lists of cell names.

      For example, if the binding YAML contains 'pin' and 'flags' cell names
      for the 'gpio' specifier space, like this:

          gpio-cells:
          - pin
          - flags

      Then the Binding object will have a 'specifier2cells' attribute mapping
      "gpio" to ["pin", "flags"]. A missing key should be interpreted as zero
      cells.

    raw:
      The binding as an object parsed from YAML.

    bus:
      If nodes with this binding's 'compatible' describe a bus, a string
      describing the bus type (like "i2c") or a list describing supported
      protocols (like ["i3c", "i2c"]). None otherwise.

      Note that this is the raw value from the binding where it can be
      a string or a list. Use "buses" instead unless you need the raw
      value, where "buses" is always a list.

    buses:
      Deprived property from 'bus' where 'buses' is a list of bus(es),
      for example, ["i2c"] or ["i3c", "i2c"]. Or an empty list if there is
      no 'bus:' in this binding.

    on_bus:
      If nodes with this binding's 'compatible' appear on a bus, a string
      describing the bus type (like "i2c"). None otherwise.

    child_binding:
      If this binding describes the properties of child nodes, then
      this is a Binding object for those children; it is None otherwise.
      A Binding object's 'child_binding.child_binding' is not None if there
      are multiple levels of 'child-binding' descriptions in the binding.
    """

    def __init__(self, path, fname2path, raw=None,
                 require_compatible=True, require_description=True):
        """
        Binding constructor.

        path:
          Path to binding YAML file. May be None.

        fname2path:
          Map from include files to their absolute paths. Must
          not be None, but may be empty.

        raw:
          Optional raw content in the binding.
          This does not have to have any "include:" lines resolved.
          May be left out, in which case 'path' is opened and read.
          This can be used to resolve child bindings, for example.

        require_compatible:
          If True, it is an error if the binding does not contain a
          "compatible:" line. If False, a missing "compatible:" is
          not an error. Either way, "compatible:" must be a string
          if it is present in the binding.

        require_description:
          If True, it is an error if the binding does not contain a
          "description:" line. If False, a missing "description:" is
          not an error. Either way, "description:" must be a string
          if it is present in the binding.
        """
        self.path = path
        self._fname2path = fname2path

        if raw is None:
            with open(path, encoding="utf-8") as f:
                raw = yaml.load(f, Loader=_BindingLoader)

        # Merge any included files into self.raw. This also pulls in
        # inherited child binding definitions, so it has to be done
        # before initializing those.
        self.raw = self._merge_includes(raw, self.path)

        # Recursively initialize any child bindings. These don't
        # require a 'compatible' or 'description' to be well defined,
        # but they must be dicts.
        if "child-binding" in raw:
            if not isinstance(raw["child-binding"], dict):
                _err(f"malformed 'child-binding:' in {self.path}, "
                     "expected a binding (dictionary with keys/values)")
            self.child_binding = Binding(path, fname2path,
                                         raw=raw["child-binding"],
                                         require_compatible=False,
                                         require_description=False)
        else:
            self.child_binding = None

        # Make sure this is a well defined object.
        self._check(require_compatible, require_description)

        # Initialize look up tables.
        self.prop2specs = OrderedDict()
        for prop_name in self.raw.get("properties", {}).keys():
            self.prop2specs[prop_name] = PropertySpec(prop_name, self)
        self.specifier2cells = OrderedDict()
        for key, val in self.raw.items():
            if key.endswith("-cells"):
                self.specifier2cells[key[:-len("-cells")]] = val

    def __repr__(self):
        if self.compatible:
            compat = f" for compatible '{self.compatible}'"
        else:
            compat = ""
        return f"<Binding {os.path.basename(self.path)}" + compat + ">"

    @property
    def description(self):
        "See the class docstring"
        return self.raw['description']

    @property
    def compatible(self):
        "See the class docstring"
        return self.raw.get('compatible')

    @property
    def bus(self):
        "See the class docstring"
        return self.raw.get('bus')

    @property
    def buses(self):
        "See the class docstring"
        if self.raw.get('bus') is not None:
            return self._buses
        else:
            return []

    @property
    def on_bus(self):
        "See the class docstring"
        return self.raw.get('on-bus')

    def _merge_includes(self, raw, binding_path):
        # Constructor helper. Merges included files in
        # 'raw["include"]' into 'raw' using 'self._include_paths' as a
        # source of include files, removing the "include" key while
        # doing so.
        #
        # This treats 'binding_path' as the binding file being built up
        # and uses it for error messages.

        if "include" not in raw:
            return raw

        include = raw.pop("include")

        # First, merge the included files together. If more than one included
        # file has a 'required:' for a particular property, OR the values
        # together, so that 'required: true' wins.

        merged = {}

        if isinstance(include, str):
            # Simple scalar string case
            _merge_props(merged, self._load_raw(include), None, binding_path,
                         False)
        elif isinstance(include, list):
            # List of strings and maps. These types may be intermixed.
            for elem in include:
                if isinstance(elem, str):
                    _merge_props(merged, self._load_raw(elem), None,
                                 binding_path, False)
                elif isinstance(elem, dict):
                    name = elem.pop('name', None)
                    allowlist = elem.pop('property-allowlist', None)
                    blocklist = elem.pop('property-blocklist', None)
                    child_filter = elem.pop('child-binding', None)

                    if elem:
                        # We've popped out all the valid keys.
                        _err(f"'include:' in {binding_path} should not have "
                             f"these unexpected contents: {elem}")

                    _check_include_dict(name, allowlist, blocklist,
                                        child_filter, binding_path)

                    contents = self._load_raw(name)

                    _filter_properties(contents, allowlist, blocklist,
                                       child_filter, binding_path)
                    _merge_props(merged, contents, None, binding_path, False)
                else:
                    _err(f"all elements in 'include:' in {binding_path} "
                         "should be either strings or maps with a 'name' key "
                         "and optional 'property-allowlist' or "
                         f"'property-blocklist' keys, but got: {elem}")
        else:
            # Invalid item.
            _err(f"'include:' in {binding_path} "
                 f"should be a string or list, but has type {type(include)}")

        # Next, merge the merged included files into 'raw'. Error out if
        # 'raw' has 'required: false' while the merged included files have
        # 'required: true'.

        _merge_props(raw, merged, None, binding_path, check_required=True)

        return raw

    def _load_raw(self, fname):
        # Returns the contents of the binding given by 'fname' after merging
        # any bindings it lists in 'include:' into it. 'fname' is just the
        # basename of the file, so we check that there aren't multiple
        # candidates.

        path = self._fname2path.get(fname)

        if not path:
            _err(f"'{fname}' not found")

        with open(path, encoding="utf-8") as f:
            contents = yaml.load(f, Loader=_BindingLoader)

        return self._merge_includes(contents, path)

    def _check(self, require_compatible, require_description):
        # Does sanity checking on the binding.

        raw = self.raw

        if "compatible" in raw:
            compatible = raw["compatible"]
            if not isinstance(compatible, str):
                _err(f"malformed 'compatible: {compatible}' "
                     f"field in {self.path} - "
                     f"should be a string, not {type(compatible).__name__}")
        elif require_compatible:
            _err(f"missing 'compatible' in {self.path}")

        if "description" in raw:
            description = raw["description"]
            if not isinstance(description, str) or not description:
                _err(f"malformed or empty 'description' in {self.path}")
        elif require_description:
            _err(f"missing 'description' in {self.path}")

        # Allowed top-level keys. The 'include' key should have been
        # removed by _load_raw() already.
        ok_top = {"description", "compatible", "bus", "on-bus",
                  "properties", "child-binding"}

        # Descriptive errors for legacy bindings.
        legacy_errors = {
            "#cells": "expected *-cells syntax",
            "child": "use 'bus: <bus>' instead",
            "child-bus": "use 'bus: <bus>' instead",
            "parent": "use 'on-bus: <bus>' instead",
            "parent-bus": "use 'on-bus: <bus>' instead",
            "sub-node": "use 'child-binding' instead",
            "title": "use 'description' instead",
        }

        for key in raw:
            if key in legacy_errors:
                _err(f"legacy '{key}:' in {self.path}, {legacy_errors[key]}")

            if key not in ok_top and not key.endswith("-cells"):
                _err(f"unknown key '{key}' in {self.path}, "
                     "expected one of {', '.join(ok_top)}, or *-cells")

        if "bus" in raw:
            bus = raw["bus"]
            if not isinstance(bus, str) and \
               (not isinstance(bus, list) and \
                not all(isinstance(elem, str) for elem in bus)):
                _err(f"malformed 'bus:' value in {self.path}, "
                     "expected string or list of strings")

            if isinstance(bus, list):
                self._buses = bus
            else:
                # Convert bus into a list
                self._buses = [bus]

        if "on-bus" in raw and \
           not isinstance(raw["on-bus"], str):
            _err(f"malformed 'on-bus:' value in {self.path}, "
                 "expected string")

        self._check_properties()

        for key, val in raw.items():
            if key.endswith("-cells"):
                if not isinstance(val, list) or \
                   not all(isinstance(elem, str) for elem in val):
                    _err(f"malformed '{key}:' in {self.path}, "
                         "expected a list of strings")

    def _check_properties(self):
        # _check() helper for checking the contents of 'properties:'.

        raw = self.raw

        if "properties" not in raw:
            return

        ok_prop_keys = {"description", "type", "required",
                        "enum", "const", "default", "deprecated",
                        "specifier-space"}

        for prop_name, options in raw["properties"].items():
            for key in options:
                if key not in ok_prop_keys:
                    _err(f"unknown setting '{key}' in "
                         f"'properties: {prop_name}: ...' in {self.path}, "
                         f"expected one of {', '.join(ok_prop_keys)}")

            _check_prop_by_type(prop_name, options, self.path)

            for true_false_opt in ["required", "deprecated"]:
                if true_false_opt in options:
                    option = options[true_false_opt]
                    if not isinstance(option, bool):
                        _err(f"malformed '{true_false_opt}:' setting '{option}' "
                             f"for '{prop_name}' in 'properties' in {self.path}, "
                             "expected true/false")

            if options.get("deprecated") and options.get("required"):
                _err(f"'{prop_name}' in 'properties' in {self.path} should not "
                      "have both 'deprecated' and 'required' set")

            if "description" in options and \
               not isinstance(options["description"], str):
                _err("missing, malformed, or empty 'description' for "
                     f"'{prop_name}' in 'properties' in {self.path}")

            if "enum" in options and not isinstance(options["enum"], list):
                _err(f"enum in {self.path} for property '{prop_name}' "
                     "is not a list")


def bindings_from_paths(yaml_paths, ignore_errors=False):
    """
    Get a list of Binding objects from the yaml files 'yaml_paths'.

    If 'ignore_errors' is True, YAML files that cause an EDTError when
    loaded are ignored. (No other exception types are silenced.)
    """

    ret = []
    fname2path = {os.path.basename(path): path for path in yaml_paths}
    for path in yaml_paths:
        try:
            ret.append(Binding(path, fname2path))
        except EDTError:
            if ignore_errors:
                continue
            raise

    return ret

class PropertySpec:
    """
    Represents a "property specification", i.e. the description of a
    property provided by a binding file, like its type and description.

    These attributes are available on PropertySpec objects:

    binding:
      The Binding object which defined this property.

    name:
      The property's name.

    path:
      The file where this property was defined. In case a binding includes
      other bindings, this is the file where the property was last modified.

    type:
      The type of the property as a string, as given in the binding.

    description:
      The free-form description of the property as a string, or None.

    enum:
      A list of values the property may take as given in the binding, or None.

    enum_tokenizable:
      True if enum is not None and all the values in it are tokenizable;
      False otherwise.

      A property must have string type and an "enum:" in its binding to be
      tokenizable. Additionally, the "enum:" values must be unique after
      converting all non-alphanumeric characters to underscores (so "foo bar"
      and "foo_bar" in the same "enum:" would not be tokenizable).

    enum_upper_tokenizable:
      Like 'enum_tokenizable', with the additional restriction that the
      "enum:" values must be unique after uppercasing and converting
      non-alphanumeric characters to underscores.

    const:
      The property's constant value as given in the binding, or None.

    default:
      The property's default value as given in the binding, or None.

    deprecated:
      True if the property is deprecated; False otherwise.

    required:
      True if the property is marked required; False otherwise.

    specifier_space:
      The specifier space for the property as given in the binding, or None.
    """

    def __init__(self, name, binding):
        self.binding = binding
        self.name = name
        self._raw = self.binding.raw["properties"][name]

    def __repr__(self):
        return f"<PropertySpec {self.name} type '{self.type}'>"

    @property
    def path(self):
        "See the class docstring"
        return self.binding.path

    @property
    def type(self):
        "See the class docstring"
        return self._raw["type"]

    @property
    def description(self):
        "See the class docstring"
        return self._raw.get("description")

    @property
    def enum(self):
        "See the class docstring"
        return self._raw.get("enum")

    @property
    def enum_tokenizable(self):
        "See the class docstring"
        if not hasattr(self, '_enum_tokenizable'):
            if self.type != 'string' or self.enum is None:
                self._enum_tokenizable = False
            else:
                # Saving _as_tokens here lets us reuse it in
                # enum_upper_tokenizable.
                self._as_tokens = [re.sub(_NOT_ALPHANUM_OR_UNDERSCORE,
                                          '_', value)
                                   for value in self.enum]
                self._enum_tokenizable = (len(self._as_tokens) ==
                                          len(set(self._as_tokens)))

        return self._enum_tokenizable

    @property
    def enum_upper_tokenizable(self):
        "See the class docstring"
        if not hasattr(self, '_enum_upper_tokenizable'):
            if not self.enum_tokenizable:
                self._enum_upper_tokenizable = False
            else:
                self._enum_upper_tokenizable = \
                    (len(self._as_tokens) ==
                     len(set(x.upper() for x in self._as_tokens)))
        return self._enum_upper_tokenizable

    @property
    def const(self):
        "See the class docstring"
        return self._raw.get("const")

    @property
    def default(self):
        "See the class docstring"
        return self._raw.get("default")

    @property
    def required(self):
        "See the class docstring"
        return self._raw.get("required", False)

    @property
    def deprecated(self):
        "See the class docstring"
        return self._raw.get("deprecated", False)

    @property
    def specifier_space(self):
        "See the class docstring"
        return self._raw.get("specifier-space")


class EDTError(Exception):
    "Exception raised for devicetree- and binding-related errors"

#
# Public global functions
#


def load_vendor_prefixes_txt(vendor_prefixes):
    """Load a vendor-prefixes.txt file and return a dict
    representation mapping a vendor prefix to the vendor name.
    """
    vnd2vendor = {}
    with open(vendor_prefixes, 'r', encoding='utf-8') as f:
        for line in f:
            line = line.strip()

            if not line or line.startswith('#'):
                # Comment or empty line.
                continue

            # Other lines should be in this form:
            #
            # <vnd><TAB><vendor>
            vnd_vendor = line.split('\t', 1)
            assert len(vnd_vendor) == 2, line
            vnd2vendor[vnd_vendor[0]] = vnd_vendor[1]
    return vnd2vendor

#
# Private global functions
#


def _dt_compats(dt):
    # Returns a set() with all 'compatible' strings in the devicetree
    # represented by dt (a dtlib.DT instance)

    return {compat
            for node in dt.node_iter()
                if "compatible" in node.props
                    for compat in node.props["compatible"].to_strings()}


def _binding_paths(bindings_dirs):
    # Returns a list with the paths to all bindings (.yaml files) in
    # 'bindings_dirs'

    binding_paths = []

    for bindings_dir in bindings_dirs:
        for root, _, filenames in os.walk(bindings_dir):
            for filename in filenames:
                if filename.endswith(".yaml") or filename.endswith(".yml"):
                    binding_paths.append(os.path.join(root, filename))

    return binding_paths


def _binding_inc_error(msg):
    # Helper for reporting errors in the !include implementation

    raise yaml.constructor.ConstructorError(None, None, "error: " + msg)


def _check_include_dict(name, allowlist, blocklist, child_filter,
                        binding_path):
    # Check that an 'include:' named 'name' with property-allowlist
    # 'allowlist', property-blocklist 'blocklist', and
    # child-binding filter 'child_filter' has valid structure.

    if name is None:
        _err(f"'include:' element in {binding_path} "
             "should have a 'name' key")

    if allowlist is not None and blocklist is not None:
        _err(f"'include:' of file '{name}' in {binding_path} "
             "should not specify both 'property-allowlist:' "
             "and 'property-blocklist:'")

    while child_filter is not None:
        child_copy = deepcopy(child_filter)
        child_allowlist = child_copy.pop('property-allowlist', None)
        child_blocklist = child_copy.pop('property-blocklist', None)
        next_child_filter = child_copy.pop('child-binding', None)

        if child_copy:
            # We've popped out all the valid keys.
            _err(f"'include:' of file '{name}' in {binding_path} "
                 "should not have these unexpected contents in a "
                 f"'child-binding': {child_copy}")

        if child_allowlist is not None and child_blocklist is not None:
            _err(f"'include:' of file '{name}' in {binding_path} "
                 "should not specify both 'property-allowlist:' and "
                 "'property-blocklist:' in a 'child-binding:'")

        child_filter = next_child_filter


def _filter_properties(raw, allowlist, blocklist, child_filter,
                       binding_path):
    # Destructively modifies 'raw["properties"]' and
    # 'raw["child-binding"]', if they exist, according to
    # 'allowlist', 'blocklist', and 'child_filter'.

    props = raw.get('properties')
    _filter_properties_helper(props, allowlist, blocklist, binding_path)

    child_binding = raw.get('child-binding')
    while child_filter is not None and child_binding is not None:
        _filter_properties_helper(child_binding.get('properties'),
                                  child_filter.get('property-allowlist'),
                                  child_filter.get('property-blocklist'),
                                  binding_path)
        child_filter = child_filter.get('child-binding')
        child_binding = child_binding.get('child-binding')


def _filter_properties_helper(props, allowlist, blocklist, binding_path):
    if props is None or (allowlist is None and blocklist is None):
        return

    _check_prop_filter('property-allowlist', allowlist, binding_path)
    _check_prop_filter('property-blocklist', blocklist, binding_path)

    if allowlist is not None:
        allowset = set(allowlist)
        to_del = [prop for prop in props if prop not in allowset]
    else:
        blockset = set(blocklist)
        to_del = [prop for prop in props if prop in blockset]

    for prop in to_del:
        del props[prop]


def _check_prop_filter(name, value, binding_path):
    # Ensure an include: ... property-allowlist or property-blocklist
    # is a list.

    if value is None:
        return

    if not isinstance(value, list):
        _err(f"'{name}' value {value} in {binding_path} should be a list")


def _merge_props(to_dict, from_dict, parent, binding_path, check_required):
    # Recursively merges 'from_dict' into 'to_dict', to implement 'include:'.
    #
    # If 'from_dict' and 'to_dict' contain a 'required:' key for the same
    # property, then the values are ORed together.
    #
    # If 'check_required' is True, then an error is raised if 'from_dict' has
    # 'required: true' while 'to_dict' has 'required: false'. This prevents
    # bindings from "downgrading" requirements from bindings they include,
    # which might help keep bindings well-organized.
    #
    # It's an error for most other keys to appear in both 'from_dict' and
    # 'to_dict'. When it's not an error, the value in 'to_dict' takes
    # precedence.
    #
    # 'parent' is the name of the parent key containing 'to_dict' and
    # 'from_dict', and 'binding_path' is the path to the top-level binding.
    # These are used to generate errors for sketchy property overwrites.

    for prop in from_dict:
        if isinstance(to_dict.get(prop), dict) and \
           isinstance(from_dict[prop], dict):
            _merge_props(to_dict[prop], from_dict[prop], prop, binding_path,
                         check_required)
        elif prop not in to_dict:
            to_dict[prop] = from_dict[prop]
        elif _bad_overwrite(to_dict, from_dict, prop, check_required):
            _err(f"{binding_path} (in '{parent}'): '{prop}' "
                 f"from included file overwritten ('{from_dict[prop]}' "
                 f"replaced with '{to_dict[prop]}')")
        elif prop == "required":
            # Need a separate check here, because this code runs before
            # Binding._check()
            if not (isinstance(from_dict["required"], bool) and
                    isinstance(to_dict["required"], bool)):
                _err(f"malformed 'required:' setting for '{parent}' in "
                     f"'properties' in {binding_path}, expected true/false")

            # 'required: true' takes precedence
            to_dict["required"] = to_dict["required"] or from_dict["required"]


def _bad_overwrite(to_dict, from_dict, prop, check_required):
    # _merge_props() helper. Returns True in cases where it's bad that
    # to_dict[prop] takes precedence over from_dict[prop].

    if to_dict[prop] == from_dict[prop]:
        return False

    # These are overridden deliberately
    if prop in {"title", "description", "compatible"}:
        return False

    if prop == "required":
        if not check_required:
            return False
        return from_dict[prop] and not to_dict[prop]

    return True


def _binding_include(loader, node):
    # Implements !include, for backwards compatibility. '!include [foo, bar]'
    # just becomes [foo, bar].

    if isinstance(node, yaml.ScalarNode):
        # !include foo.yaml
        return [loader.construct_scalar(node)]

    if isinstance(node, yaml.SequenceNode):
        # !include [foo.yaml, bar.yaml]
        return loader.construct_sequence(node)

    _binding_inc_error("unrecognised node type in !include statement")


def _check_prop_by_type(prop_name, options, binding_path):
    # Binding._check_properties() helper. Checks 'type:', 'default:',
    # 'const:' and # 'specifier-space:' for the property named 'prop_name'

    prop_type = options.get("type")
    default = options.get("default")
    const = options.get("const")

    if prop_type is None:
        _err(f"missing 'type:' for '{prop_name}' in 'properties' in "
             f"{binding_path}")

    ok_types = {"boolean", "int", "array", "uint8-array", "string",
                "string-array", "phandle", "phandles", "phandle-array",
                "path", "compound"}

    if prop_type not in ok_types:
        _err(f"'{prop_name}' in 'properties:' in {binding_path} "
             f"has unknown type '{prop_type}', expected one of " +
             ", ".join(ok_types))

    if "specifier-space" in options and prop_type != "phandle-array":
        _err(f"'specifier-space' in 'properties: {prop_name}' "
             f"has type '{prop_type}', expected 'phandle-array'")

    if prop_type == "phandle-array":
        if not prop_name.endswith("s") and not "specifier-space" in options:
            _err(f"'{prop_name}' in 'properties:' in {binding_path} "
                 f"has type 'phandle-array' and its name does not end in 's', "
                 f"but no 'specifier-space' was provided.")

    const_types = {"int", "array", "uint8-array", "string", "string-array"}
    if const and prop_type not in const_types:
        _err(f"const in {binding_path} for property '{prop_name}' "
             f"has type '{prop_type}', expected one of " +
             ", ".join(const_types))

    # Check default

    if default is None:
        return

    if prop_type in {"boolean", "compound", "phandle", "phandles",
                     "phandle-array", "path"}:
        _err("'default:' can't be combined with "
             f"'type: {prop_type}' for '{prop_name}' in "
             f"'properties:' in {binding_path}")

    def ok_default():
        # Returns True if 'default' is an okay default for the property's type

        if prop_type == "int" and isinstance(default, int) or \
           prop_type == "string" and isinstance(default, str):
            return True

        # array, uint8-array, or string-array

        if not isinstance(default, list):
            return False

        if prop_type == "array" and \
           all(isinstance(val, int) for val in default):
            return True

        if prop_type == "uint8-array" and \
           all(isinstance(val, int) and 0 <= val <= 255 for val in default):
            return True

        # string-array
        return all(isinstance(val, str) for val in default)

    if not ok_default():
        _err(f"'default: {default}' is invalid for '{prop_name}' "
             f"in 'properties:' in {binding_path}, "
             f"which has type {prop_type}")


def _translate(addr, node):
    # Recursively translates 'addr' on 'node' to the address space(s) of its
    # parent(s), by looking at 'ranges' properties. Returns the translated
    # address.
    #
    # node:
    #   dtlib.Node instance

    if not node.parent or "ranges" not in node.parent.props:
        # No translation
        return addr

    if not node.parent.props["ranges"].value:
        # DT spec.: "If the property is defined with an <empty> value, it
        # specifies that the parent and child address space is identical, and
        # no address translation is required."
        #
        # Treat this the same as a 'range' that explicitly does a one-to-one
        # mapping, as opposed to there not being any translation.
        return _translate(addr, node.parent)

    # Gives the size of each component in a translation 3-tuple in 'ranges'
    child_address_cells = _address_cells(node)
    parent_address_cells = _address_cells(node.parent)
    child_size_cells = _size_cells(node)

    # Number of cells for one translation 3-tuple in 'ranges'
    entry_cells = child_address_cells + parent_address_cells + child_size_cells

    for raw_range in _slice(node.parent, "ranges", 4*entry_cells,
                            f"4*(<#address-cells> (= {child_address_cells}) + "
                            "<#address-cells for parent> "
                            f"(= {parent_address_cells}) + "
                            f"<#size-cells> (= {child_size_cells}))"):
        child_addr = to_num(raw_range[:4*child_address_cells])
        raw_range = raw_range[4*child_address_cells:]

        parent_addr = to_num(raw_range[:4*parent_address_cells])
        raw_range = raw_range[4*parent_address_cells:]

        child_len = to_num(raw_range)

        if child_addr <= addr < child_addr + child_len:
            # 'addr' is within range of a translation in 'ranges'. Recursively
            # translate it and return the result.
            return _translate(parent_addr + addr - child_addr, node.parent)

    # 'addr' is not within range of any translation in 'ranges'
    return addr


def _add_names(node, names_ident, objs):
    # Helper for registering names from <foo>-names properties.
    #
    # node:
    #   edtlib.Node instance
    #
    # names-ident:
    #   The <foo> part of <foo>-names, e.g. "reg" for "reg-names"
    #
    # objs:
    #   list of objects whose .name field should be set

    full_names_ident = names_ident + "-names"

    if full_names_ident in node.props:
        names = node.props[full_names_ident].to_strings()
        if len(names) != len(objs):
            _err(f"{full_names_ident} property in {node.path} "
                 f"in {node.dt.filename} has {len(names)} strings, "
                 f"expected {len(objs)} strings")

        for obj, name in zip(objs, names):
            if obj is None:
                continue
            obj.name = name
    else:
        for obj in objs:
            if obj is not None:
                obj.name = None


def _interrupt_parent(node):
    # Returns the node pointed at by the closest 'interrupt-parent', searching
    # the parents of 'node'. As of writing, this behavior isn't specified in
    # the DT spec., but seems to match what some .dts files except.

    start_node = node

    while node:
        if "interrupt-parent" in node.props:
            return node.props["interrupt-parent"].to_node()
        node = node.parent

    _err(f"{start_node!r} has an 'interrupts' property, but neither the node "
         f"nor any of its parents has an 'interrupt-parent' property")


def _interrupts(node):
    # Returns a list of (<controller>, <data>) tuples, with one tuple per
    # interrupt generated by 'node'. <controller> is the destination of the
    # interrupt (possibly after mapping through an 'interrupt-map'), and <data>
    # the data associated with the interrupt (as a 'bytes' object).

    # Takes precedence over 'interrupts' if both are present
    if "interrupts-extended" in node.props:
        prop = node.props["interrupts-extended"]
        return [_map_interrupt(node, iparent, spec)
                for iparent, spec in _phandle_val_list(prop, "interrupt")]

    if "interrupts" in node.props:
        # Treat 'interrupts' as a special case of 'interrupts-extended', with
        # the same interrupt parent for all interrupts

        iparent = _interrupt_parent(node)
        interrupt_cells = _interrupt_cells(iparent)

        return [_map_interrupt(node, iparent, raw)
                for raw in _slice(node, "interrupts", 4*interrupt_cells,
                                  "4*<#interrupt-cells>")]

    return []


def _map_interrupt(child, parent, child_spec):
    # Translates an interrupt headed from 'child' to 'parent' with data
    # 'child_spec' through any 'interrupt-map' properties. Returns a
    # (<controller>, <data>) tuple with the final destination after mapping.

    if "interrupt-controller" in parent.props:
        return (parent, child_spec)

    def own_address_cells(node):
        # Used for parents pointed at by 'interrupt-map'. We can't use
        # _address_cells(), because it's the #address-cells property on 'node'
        # itself that matters.

        address_cells = node.props.get("#address-cells")
        if not address_cells:
            _err(f"missing #address-cells on {node!r} "
                 "(while handling interrupt-map)")
        return address_cells.to_num()

    def spec_len_fn(node):
        # Can't use _address_cells() here, because it's the #address-cells
        # property on 'node' itself that matters
        return own_address_cells(node) + _interrupt_cells(node)

    parent, raw_spec = _map(
        "interrupt", child, parent, _raw_unit_addr(child) + child_spec,
        spec_len_fn, require_controller=True)

    # Strip the parent unit address part, if any
    return (parent, raw_spec[4*own_address_cells(parent):])


def _map_phandle_array_entry(child, parent, child_spec, basename):
    # Returns a (<controller>, <data>) tuple with the final destination after
    # mapping through any '<basename>-map' (e.g. gpio-map) properties. See
    # _map_interrupt().

    def spec_len_fn(node):
        prop_name = f"#{basename}-cells"
        if prop_name not in node.props:
            _err(f"expected '{prop_name}' property on {node!r} "
                 f"(referenced by {child!r})")
        return node.props[prop_name].to_num()

    # Do not require <prefix>-controller for anything but interrupts for now
    return _map(basename, child, parent, child_spec, spec_len_fn,
                require_controller=False)


def _map(prefix, child, parent, child_spec, spec_len_fn, require_controller):
    # Common code for mapping through <prefix>-map properties, e.g.
    # interrupt-map and gpio-map.
    #
    # prefix:
    #   The prefix, e.g. "interrupt" or "gpio"
    #
    # child:
    #   The "sender", e.g. the node with 'interrupts = <...>'
    #
    # parent:
    #   The "receiver", e.g. a node with 'interrupt-map = <...>' or
    #   'interrupt-controller' (no mapping)
    #
    # child_spec:
    #   The data associated with the interrupt/GPIO/etc., as a 'bytes' object,
    #   e.g. <1 2> for 'foo-gpios = <&gpio1 1 2>'.
    #
    # spec_len_fn:
    #   Function called on a parent specified in a *-map property to get the
    #   length of the parent specifier (data after phandle in *-map), in cells
    #
    # require_controller:
    #   If True, the final controller node after mapping is required to have
    #   to have a <prefix>-controller property.

    map_prop = parent.props.get(prefix + "-map")
    if not map_prop:
        if require_controller and prefix + "-controller" not in parent.props:
            _err(f"expected '{prefix}-controller' property on {parent!r} "
                 f"(referenced by {child!r})")

        # No mapping
        return (parent, child_spec)

    masked_child_spec = _mask(prefix, child, parent, child_spec)

    raw = map_prop.value
    while raw:
        if len(raw) < len(child_spec):
            _err(f"bad value for {map_prop!r}, missing/truncated child data")
        child_spec_entry = raw[:len(child_spec)]
        raw = raw[len(child_spec):]

        if len(raw) < 4:
            _err(f"bad value for {map_prop!r}, missing/truncated phandle")
        phandle = to_num(raw[:4])
        raw = raw[4:]

        # Parent specified in *-map
        map_parent = parent.dt.phandle2node.get(phandle)
        if not map_parent:
            _err(f"bad phandle ({phandle}) in {map_prop!r}")

        map_parent_spec_len = 4*spec_len_fn(map_parent)
        if len(raw) < map_parent_spec_len:
            _err(f"bad value for {map_prop!r}, missing/truncated parent data")
        parent_spec = raw[:map_parent_spec_len]
        raw = raw[map_parent_spec_len:]

        # Got one *-map row. Check if it matches the child data.
        if child_spec_entry == masked_child_spec:
            # Handle *-map-pass-thru
            parent_spec = _pass_thru(
                prefix, child, parent, child_spec, parent_spec)

            # Found match. Recursively map and return it.
            return _map(prefix, parent, map_parent, parent_spec, spec_len_fn,
                        require_controller)

    _err(f"child specifier for {child!r} ({child_spec}) "
         f"does not appear in {map_prop!r}")


def _mask(prefix, child, parent, child_spec):
    # Common code for handling <prefix>-mask properties, e.g. interrupt-mask.
    # See _map() for the parameters.

    mask_prop = parent.props.get(prefix + "-map-mask")
    if not mask_prop:
        # No mask
        return child_spec

    mask = mask_prop.value
    if len(mask) != len(child_spec):
        _err(f"{child!r}: expected '{prefix}-mask' in {parent!r} "
             f"to be {len(child_spec)} bytes, is {len(mask)} bytes")

    return _and(child_spec, mask)


def _pass_thru(prefix, child, parent, child_spec, parent_spec):
    # Common code for handling <prefix>-map-thru properties, e.g.
    # interrupt-pass-thru.
    #
    # parent_spec:
    #   The parent data from the matched entry in the <prefix>-map property
    #
    # See _map() for the other parameters.

    pass_thru_prop = parent.props.get(prefix + "-map-pass-thru")
    if not pass_thru_prop:
        # No pass-thru
        return parent_spec

    pass_thru = pass_thru_prop.value
    if len(pass_thru) != len(child_spec):
        _err(f"{child!r}: expected '{prefix}-map-pass-thru' in {parent!r} "
             f"to be {len(child_spec)} bytes, is {len(pass_thru)} bytes")

    res = _or(_and(child_spec, pass_thru),
              _and(parent_spec, _not(pass_thru)))

    # Truncate to length of parent spec.
    return res[-len(parent_spec):]


def _raw_unit_addr(node):
    # _map_interrupt() helper. Returns the unit address (derived from 'reg' and
    # #address-cells) as a raw 'bytes'

    if 'reg' not in node.props:
        _err(f"{node!r} lacks 'reg' property "
             "(needed for 'interrupt-map' unit address lookup)")

    addr_len = 4*_address_cells(node)

    if len(node.props['reg'].value) < addr_len:
        _err(f"{node!r} has too short 'reg' property "
             "(while doing 'interrupt-map' unit address lookup)")

    return node.props['reg'].value[:addr_len]


def _and(b1, b2):
    # Returns the bitwise AND of the two 'bytes' objects b1 and b2. Pads
    # with ones on the left if the lengths are not equal.

    # Pad on the left, to equal length
    maxlen = max(len(b1), len(b2))
    return bytes(x & y for x, y in zip(b1.rjust(maxlen, b'\xff'),
                                       b2.rjust(maxlen, b'\xff')))


def _or(b1, b2):
    # Returns the bitwise OR of the two 'bytes' objects b1 and b2. Pads with
    # zeros on the left if the lengths are not equal.

    # Pad on the left, to equal length
    maxlen = max(len(b1), len(b2))
    return bytes(x | y for x, y in zip(b1.rjust(maxlen, b'\x00'),
                                       b2.rjust(maxlen, b'\x00')))


def _not(b):
    # Returns the bitwise not of the 'bytes' object 'b'

    # ANDing with 0xFF avoids negative numbers
    return bytes(~x & 0xFF for x in b)


def _phandle_val_list(prop, n_cells_name):
    # Parses a '<phandle> <value> <phandle> <value> ...' value. The number of
    # cells that make up each <value> is derived from the node pointed at by
    # the preceding <phandle>.
    #
    # prop:
    #   dtlib.Property with value to parse
    #
    # n_cells_name:
    #   The <name> part of the #<name>-cells property to look for on the nodes
    #   the phandles point to, e.g. "gpio" for #gpio-cells.
    #
    # Returns a list[Optional[tuple]].
    #
    # Each tuple in the list is a (<node>, <value>) pair, where <node>
    # is the node pointed at by <phandle>. If <phandle> does not refer
    # to a node, the entire list element is None.

    full_n_cells_name = f"#{n_cells_name}-cells"

    res = []

    raw = prop.value
    while raw:
        if len(raw) < 4:
            # Not enough room for phandle
            _err("bad value for " + repr(prop))
        phandle = to_num(raw[:4])
        raw = raw[4:]

        node = prop.node.dt.phandle2node.get(phandle)
        if not node:
            # Unspecified phandle-array element. This is valid; a 0
            # phandle value followed by no cells is an empty element.
            res.append(None)
            continue

        if full_n_cells_name not in node.props:
            _err(f"{node!r} lacks {full_n_cells_name}")

        n_cells = node.props[full_n_cells_name].to_num()
        if len(raw) < 4*n_cells:
            _err("missing data after phandle in " + repr(prop))

        res.append((node, raw[:4*n_cells]))
        raw = raw[4*n_cells:]

    return res


def _address_cells(node):
    # Returns the #address-cells setting for 'node', giving the number of <u32>
    # cells used to encode the address in the 'reg' property

    if "#address-cells" in node.parent.props:
        return node.parent.props["#address-cells"].to_num()
    return 2  # Default value per DT spec.


def _size_cells(node):
    # Returns the #size-cells setting for 'node', giving the number of <u32>
    # cells used to encode the size in the 'reg' property

    if "#size-cells" in node.parent.props:
        return node.parent.props["#size-cells"].to_num()
    return 1  # Default value per DT spec.


def _interrupt_cells(node):
    # Returns the #interrupt-cells property value on 'node', erroring out if
    # 'node' has no #interrupt-cells property

    if "#interrupt-cells" not in node.props:
        _err(f"{node!r} lacks #interrupt-cells")
    return node.props["#interrupt-cells"].to_num()


def _slice(node, prop_name, size, size_hint):
    # Splits node.props[prop_name].value into 'size'-sized chunks, returning a
    # list of chunks. Raises EDTError if the length of the property is not
    # evenly divisible by 'size'. 'size_hint' is a string shown on errors that
    # gives a hint on how 'size' was calculated.

    raw = node.props[prop_name].value
    if len(raw) % size:
        _err(f"'{prop_name}' property in {node!r} has length {len(raw)}, "
             f"which is not evenly divisible by {size} (= {size_hint}). "
             "Note that #*-cells properties come either from the parent node or "
             "from the controller (in the case of 'interrupts').")

    return [raw[i:i + size] for i in range(0, len(raw), size)]


def _check_dt(dt):
    # Does devicetree sanity checks. dtlib is meant to be general and
    # anything-goes except for very special properties like phandle, but in
    # edtlib we can be pickier.

    # Check that 'status' has one of the values given in the devicetree spec.

    # Accept "ok" for backwards compatibility
    ok_status = {"ok", "okay", "disabled", "reserved", "fail", "fail-sss"}

    for node in dt.node_iter():
        if "status" in node.props:
            try:
                status_val = node.props["status"].to_string()
            except DTError as e:
                # The error message gives the path
                _err(str(e))

            if status_val not in ok_status:
                _err(f"unknown 'status' value \"{status_val}\" in {node.path} "
                     f"in {node.dt.filename}, expected one of " +
                     ", ".join(ok_status) +
                     " (see the devicetree specification)")

        ranges_prop = node.props.get("ranges")
        if ranges_prop:
            if ranges_prop.type not in (Type.EMPTY, Type.NUMS):
                _err(f"expected 'ranges = < ... >;' in {node.path} in "
                     f"{node.dt.filename}, not '{ranges_prop}' "
                     "(see the devicetree specification)")


def _err(msg):
    raise EDTError(msg)

# Logging object
_LOG = logging.getLogger(__name__)

# Regular expression for non-alphanumeric-or-underscore characters.
_NOT_ALPHANUM_OR_UNDERSCORE = re.compile(r'\W', re.ASCII)


def str_as_token(val):
    """Return a canonical representation of a string as a C token.

    This converts special characters in 'val' to underscores, and
    returns the result."""

    return re.sub(_NOT_ALPHANUM_OR_UNDERSCORE, '_', val)


# Custom PyYAML binding loader class to avoid modifying yaml.Loader directly,
# which could interfere with YAML loading in clients
class _BindingLoader(Loader):
    pass


# Add legacy '!include foo.yaml' handling
_BindingLoader.add_constructor("!include", _binding_include)

#
# "Default" binding for properties which are defined by the spec.
#
# Zephyr: do not change the _DEFAULT_PROP_TYPES keys without
# updating the documentation for the DT_PROP() macro in
# include/devicetree.h.
#

_DEFAULT_PROP_TYPES = {
    "compatible": "string-array",
    "status": "string",
    "reg": "array",
    "reg-names": "string-array",
    "label": "string",
    "interrupts": "array",
    "interrupts-extended": "compound",
    "interrupt-names": "string-array",
    "interrupt-controller": "boolean",
}

_STATUS_ENUM = "ok okay disabled reserved fail fail-sss".split()

def _raw_default_property_for(name):
    ret = {
        'type': _DEFAULT_PROP_TYPES[name],
        'required': False,
    }
    if name == 'status':
        ret['enum'] = _STATUS_ENUM
    return ret

_DEFAULT_PROP_BINDING = Binding(
    None, {},
    raw={
        'properties': {
            name: _raw_default_property_for(name)
            for name in _DEFAULT_PROP_TYPES
        },
    },
    require_compatible=False, require_description=False,
)

_DEFAULT_PROP_SPECS = {
    name: PropertySpec(name, _DEFAULT_PROP_BINDING)
    for name in _DEFAULT_PROP_TYPES
}

# A set of vendor prefixes which are grandfathered in by Linux,
# and therefore by us as well.
_VENDOR_PREFIX_ALLOWED = set([
    "at25", "bm", "devbus", "dmacap", "dsa",
    "exynos", "fsia", "fsib", "gpio-fan", "gpio-key", "gpio", "gpmc",
    "hdmi", "i2c-gpio", "keypad", "m25p", "max8952", "max8997",
    "max8998", "mpmc", "pinctrl-single", "#pinctrl-single", "PowerPC",
    "pl022", "pxa-mmc", "rcar_sound", "rotary-encoder", "s5m8767",
    "sdhci", "simple-audio-card", "st-plgpio", "st-spics", "ts",
])
