# 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 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: testedtlib.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
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

from dtlib import DT, DTError, to_num, to_nums, TYPE_EMPTY, TYPE_BYTES, \
                  TYPE_NUM, TYPE_NUMS, TYPE_STRING, TYPE_STRINGS, \
                  TYPE_PHANDLE, TYPE_PHANDLES, TYPE_PHANDLES_AND_NUMS
from 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'.

    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):
        """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.

        """
        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.dts_path = dts
        self.bindings_dirs = bindings_dirs

        self._dt = DT(dts)
        _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 "<EDT for '{}', binding directories '{}'>".format(
            self.dts_path, 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:
                _LOG.warning(
                        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)

            if binding is None:
                # Either the file is not a binding or it's a binding
                # whose compatible does not appear in the devicetree
                # (picked up via some unrelated text in the binding
                # file that happened to match a compatible).
                continue

            # 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 _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 _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()

            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)
            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)

        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)

        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))

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

    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.

    bus:
      If the node is a bus node (has a 'bus:' key in its binding), then this
      attribute holds the bus type, e.g. "i2c" or "spi". If the node is not a
      bus node, then this attribute is None.

    on_bus:
      The bus the node appears on, e.g. "i2c" or "spi". 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 None.

    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("{!r} has non-hex unit address".format(self))

        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())

    @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 bus(self):
        "See the class docstring"
        if self._binding:
            return self._binding.bus
        return None

    @property
    def on_bus(self):
        "See the class docstring"
        bus_node = self.bus_node
        return bus_node.bus if bus_node else None

    @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("flash partition {!r} lacks parent or grandparent node"
                 .format(self))

        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"

        if not (self.on_bus == "spi" and "cs-gpios" in self.bus_node.props):
            return None

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

        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("index from 'regs' in {!r} ({}) is >= number of cs-gpios "
                 "in {!r} ({})".format(
                     self, cs_index, self.bus_node, len(parent_cs_lst)))

        return parent_cs_lst[cs_index]

    def __repr__(self):
        return "<Node {} in '{}', {}>".format(
            self.path, self.edt.dts_path,
            "binding " + self.binding_path if self.binding_path
                else "no 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_bus = self.on_bus

            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.
                if (compat, on_bus) in self.edt._compat2binding:
                    binding = self.edt._compat2binding[compat, on_bus]
                elif (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"
            else:
                _err(f"cannot infer binding from property: {prop}")
            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.bus:
            # 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):
        # 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)
            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)
                self.props[name] = Property(prop_spec, val, self)

    def _init_prop(self, prop_spec):
        # _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("'{}' in {} lacks 'type'".format(name, self.binding_path))

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

        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("value of property '{}' on {} in {} ({!r}) is not in 'enum' "
                 "list in {} ({!r})"
                 .format(name, self.path, self.edt.dts_path, val,
                         self.binding_path, enum))

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

        # 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):
        # _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

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

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

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

            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_type_and_default().
                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 is not 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)

        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_type_and_default().
        #
        # '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("'{}' appears in {} in {}, but is not declared in "
                     "'properties:' in {}"
                     .format(prop_name, self._node.path, self.edt.dts_path,
                             self.binding_path))

    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),
                              "4*(<#address-cells> (= {}) + <#size-cells> (= {}))"
                              .format(address_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("zero-sized 'reg' in {!r} seems meaningless (maybe you "
                     "want a size of one or #size-cells = 0 instead)"
                     .format(self._node))

            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("missing 'pinctrl-{}' property on {!r} - indices should "
                     "be contiguous and start from zero".format(i, node))

        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):
        # Parses a property like
        #
        #     <name>s = <phandle value phandle value ...>
        #     (e.g., pwms = <&foo 1 2 &bar 3 4>)
        #
        # , where each phandle points to a node that has a
        #
        #     #<name>-cells = <size>
        #
        # property that gives the number of cells in the value after the
        # phandle. These values are given names in *-cells in the binding for
        # the controller.
        #
        # Also parses any
        #
        #     <name>-names = "...", "...", ...
        #
        # Returns a list of Optional[ControllerAndData] instances.
        # An index is None if the underlying phandle-array element
        # is unspecified.

        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
            basename = "gpio"
        else:
            # Strip -s. We've already checked that the property names end in -s
            # in _check_prop_type_and_default().
            basename = prop.name[:-1]

        res = []

        for item in _phandle_val_list(prop, basename):
            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,
                                         basename)

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

            res.append(entry)

        _add_names(self._node, basename, 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("{} controller {!r} for {!r} lacks binding"
                 .format(basename, controller._node, self._node))

        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("unexpected '{}-cells:' length in binding for {!r} - {} "
                 "instead of {}"
                 .format(basename, controller._node, len(cell_names),
                         len(data_list)))

        return OrderedDict(zip(cell_names, data_list))


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
    """
    def __repr__(self):
        fields = []

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

        fields.append("controller: {}".format(self.controller))
        fields.append("data: {}".format(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

    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>;
    """
    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 re.sub(_NOT_ALPHANUM_OR_UNDERSCORE, '_', 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("enum index: {}".format(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 is None if the Binding is
      inferred from node properties. If the Binding is a child binding, then
      this will be inherited from the parent binding unless the child binding
      explicitly sets its own 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"). None otherwise.

    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

        # Make child binding compatibles match ours if they are missing.
        if self.compatible is not None:
            child = self.child_binding
            while child is not None:
                if child.compatible is None:
                    child.compatible = self.compatible
                child = child.child_binding

    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"
        if hasattr(self, '_compatible'):
            return self._compatible
        return self.raw.get('compatible')

    @compatible.setter
    def compatible(self, compatible):
        "See the class docstring"
        self._compatible = compatible

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

    @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")
        fnames = []
        if isinstance(include, str):
            fnames.append(include)
        elif isinstance(include, list):
            if not all(isinstance(elem, str) for elem in include):
                _err(f"all elements in 'include:' in {binding_path} "
                     "should be strings")
            fnames += include
        else:
            _err(f"'include:' in {binding_path} "
                 "should be a string or a list of strings")

        # 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 = {}
        for fname in fnames:
            _merge_props(merged, self._load_raw(fname), None, binding_path,
                         check_required=False)

        # 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' property in {self.path}")

        if "description" not in raw and require_description:
            _err(f"missing 'description' property in {self.path}")

        for prop in "title", "description":
            if prop in raw and (not isinstance(raw[prop], str) or
                                not raw[prop]):
                _err(f"malformed or empty '{prop}' in {self.path}")

        ok_top = {"title", "description", "compatible", "properties",
                  "bus", "on-bus", "parent-bus", "child-bus", "parent", "child",
                  "child-binding", "sub-node"}

        for prop in raw:
            if prop == "#cells": # clean error for users of legacy syntax
                _err(f"malformed '{prop}:' in {self.path}, "
                     "expected *-cells syntax")
            if prop not in ok_top and not prop.endswith("-cells"):
                _err(f"unknown key '{prop}' in {self.path}, "
                     "expected one of {', '.join(ok_top)}, or *-cells")

        for bus_key in "bus", "on-bus":
            if bus_key in raw and \
               not isinstance(raw[bus_key], str):
                _err(f"malformed '{bus_key}:' 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"}

        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_type_and_default(
                prop_name, options.get("type"),
                options.get("default"),
                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")

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


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

    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)

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


#
# 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"):
                    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 _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("{} (in '{}'): '{}' from included file overwritten "
                 "('{}' replaced with '{}')".format(
                     binding_path, parent, prop, from_dict[prop],
                     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("malformed 'required:' setting for '{}' in 'properties' "
                     "in {}, expected true/false".format(parent, binding_path))

            # '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_type_and_default(prop_name, prop_type, default, binding_path):
    # Binding._check_properties() helper. Checks 'type:' and 'default:' for the
    # property named 'prop_name'

    if prop_type is None:
        _err("missing 'type:' for '{}' in 'properties' in {}"
             .format(prop_name, 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("'{}' in 'properties:' in {} has unknown type '{}', expected one "
             "of {}".format(prop_name, binding_path, prop_type,
                            ", ".join(ok_types)))

    if prop_type == "phandle-array" and not prop_name.endswith("s"):
        _err("'{}' in 'properties:' in {} is 'type: phandle-array', but its "
             "name does not end in -s. This is required since property names "
             "like '#pwm-cells' and 'pwm-names' get derived from 'pwms', for "
             "example.".format(prop_name, binding_path))

    # 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 'type: {}' for '{}' in "
             "'properties:' in {}".format(prop_type, prop_name, 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("'default: {}' is invalid for '{}' in 'properties:' in {}, which "
             "has type {}".format(default, prop_name, binding_path, 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,
                            "4*(<#address-cells> (= {}) + "
                            "<#address-cells for parent> (= {}) + "
                            "<#size-cells> (= {}))"
                            .format(child_address_cells, parent_address_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("{} property in {} in {} has {} strings, expected {} strings"
                 .format(full_names_ident, node.path, node.dt.filename,
                         len(names), len(objs)))

        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.

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

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


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("missing #address-cells on {!r} (while handling interrupt-map)"
                 .format(node))
        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 = "#{}-cells".format(basename)
        if prop_name not in node.props:
            _err("expected '{}' property on {!r} (referenced by {!r})"
                 .format(prop_name, node, child))
        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("expected '{}-controller' property on {!r} "
                 "(referenced by {!r})".format(prefix, parent, child))

        # 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("bad value for {!r}, missing/truncated child data"
                 .format(map_prop))
        child_spec_entry = raw[:len(child_spec)]
        raw = raw[len(child_spec):]

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

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

        map_parent_spec_len = 4*spec_len_fn(map_parent)
        if len(raw) < map_parent_spec_len:
            _err("bad value for {!r}, missing/truncated parent data"
                 .format(map_prop))
        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("child specifier for {!r} ({}) does not appear in {!r}"
         .format(child, child_spec, map_prop))


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("{!r}: expected '{}-mask' in {!r} to be {} bytes, is {} bytes"
             .format(child, prefix, parent, len(child_spec), len(mask)))

    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("{!r}: expected '{}-map-pass-thru' in {!r} to be {} bytes, is {} bytes"
             .format(child, prefix, parent, len(child_spec), len(pass_thru)))

    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("{!r} lacks 'reg' property (needed for 'interrupt-map' unit "
             "address lookup)".format(node))

    addr_len = 4*_address_cells(node)

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

    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 = "#{}-cells".format(n_cells_name)

    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("{!r} lacks {}".format(node, 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("{!r} lacks #interrupt-cells".format(node))
    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("'{}' property in {!r} has length {}, which is not evenly "
             "divisible by {} (= {}). Note that #*-cells "
             "properties come either from the parent node or from the "
             "controller (in the case of 'interrupts')."
             .format(prop_name, node, len(raw), size, size_hint))

    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("unknown 'status' value \"{}\" in {} in {}, expected one "
                     "of {} (see the devicetree specification)"
                     .format(status_val, node.path, node.dt.filename,
                             ", ".join(ok_status)))

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


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)

# 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)

# Use OrderedDict instead of plain dict for YAML mappings, to preserve
# insertion order on Python 3.5 and earlier (plain dicts only preserve
# insertion order on Python 3.6+). This makes testing easier and avoids
# surprises.
#
# Adapted from
# https://stackoverflow.com/questions/5121931/in-python-how-can-you-load-yaml-mappings-as-ordereddicts.
# Hopefully this API stays stable.
_BindingLoader.add_constructor(
    yaml.resolver.BaseResolver.DEFAULT_MAPPING_TAG,
    lambda loader, node: OrderedDict(loader.construct_pairs(node)))

#
# "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
}
