# 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 .dts files and bindings at a higher level compared to
dtlib. Deals with things at the level of devices, registers, interrupts,
compatibles, bindings, etc., as opposed to dtlib, which is just a low-level
device tree parser.

Each device tree node (dtlib.Node) gets a Device instance, which has all the
information related to the device, derived from both the device tree and from
the binding for the device.

Bindings are files that describe device tree nodes. Device tree nodes are
usually mapped to bindings via their 'compatible = "..."' property, but binding
data can also come from a 'sub-node:' key in the binding for the parent device
tree node.

The top-level entry point of the library is the EDT class. EDT.__init__() takes
a .dts file to parse and the path of a directory containing bindings.
"""

import os
import re
import sys

import yaml

from dtlib import DT, DTError, to_num, to_nums

# NOTE: testedtlib.py is the test suite for this library. It can be run
# directly.

# 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 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.
#
# - Please use ""-quoted strings instead of ''-quoted strings, just to make
#   things consistent (''-quoting is more common otherwise in Python)

#
# Public classes
#


class EDT:
    """
    Represents a "high-level" view of a device tree, with a list of devices
    that each have some number of registers, etc.

    These attributes are available on EDT objects:

    devices:
      A list of Device objects for the devices

    dts_path:
      The .dts path passed to __init__()

    bindings_dir:
      The bindings directory path passed to __init__()
    """
    def __init__(self, dts, bindings_dir):
        """
        EDT constructor. This is the top-level entry point to the library.

        dts:
          Path to device tree .dts file

        bindings_dir:
          Path to directory containing bindings, in YAML format. This directory
          is recursively searched for .yaml files.
        """
        self.dts_path = dts
        self.bindings_dir = bindings_dir

        self._dt = DT(dts)

        self._init_compat2binding(bindings_dir)
        self._init_devices()

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

    def chosen_dev(self, name):
        """
        Returns the Device pointed at by the property named 'name' in /chosen,
        or None if the property is missing
        """
        try:
            chosen = self._dt.get_node("/chosen")
        except DTError:
            # No /chosen node
            return None

        if name not in chosen.props:
            return None

        path = chosen.props[name].to_string()
        try:
            return self._node2dev[self._dt.get_node(path)]
        except DTError:
            _err("{} in /chosen points to {}, which does not exist"
                 .format(name, path))

    def _init_compat2binding(self, bindings_dir):
        # Creates self._compat2binding. This is a dictionary that maps
        # (<compatible>, <bus>) tuples (both strings) to (<binding>, <path>)
        # tuples. <binding> is the binding in parsed PyYAML format, and <path>
        # the path to the binding (nice for binding-related error messages).
        #
        # For example, self._compat2binding["company,dev", "can"] contains the
        # binding/path 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] contains the binding.
        #
        # Only bindings for 'compatible' strings that appear in the device tree
        # are loaded.

        dt_compats = _dt_compats(self._dt)
        self._binding_paths = _binding_paths(bindings_dir)

        # Add '!include foo.yaml' handling.
        #
        # Do yaml.Loader.add_constructor() instead of yaml.add_constructor() to be
        # compatible with both version 3.13 and version 5.1 of PyYAML.
        #
        # TODO: Is there some 3.13/5.1-compatible way to only do this once, even
        # if multiple EDT objects are created?
        yaml.Loader.add_constructor("!include", self._binding_include)

        self._compat2binding = {}
        for binding_path in self._binding_paths:
            compat = _binding_compat(binding_path)
            if compat in dt_compats:
                binding = _load_binding(binding_path)
                self._compat2binding[compat, _binding_bus(binding)] = \
                    (binding, binding_path)

    def _binding_include(self, loader, node):
        # Implements !include. Returns a list with the YAML structures for the
        # included files (a single-element list if the !include is for a single
        # file).

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

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

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

    def _binding_include_file(self, filename):
        # _binding_include() helper for loading an !include'd file. !include
        # takes just the basename of the file, so we need to make sure there
        # aren't multiple candidates.

        paths = [path for path in self._binding_paths
                 if os.path.basename(path) == filename]

        if not paths:
            _binding_inc_error("'{}' not found".format(filename))

        if len(paths) > 1:
            _binding_inc_error("multiple candidates for '{}' in !include: {}"
                               .format(filename, ", ".join(paths)))

        with open(paths[0], encoding="utf-8") as f:
            return yaml.load(f, Loader=yaml.Loader)

    def _init_devices(self):
        # Creates a list of devices (Device objects) from the DT nodes, in
        # self.devices. 'dt' is the dtlib.DT instance for the device tree.

        # Maps dtlib.Node's to their corresponding Devices
        self._node2dev = {}

        self.devices = []

        for node in self._dt.node_iter():
            # Warning: Device.__init__() relies on parent Devices being created
            # before their children. This is guaranteed by node_iter().
            dev = Device(self, node)
            self.devices.append(dev)
            self._node2dev[node] = dev

        for dev in self.devices:
            # These depend on all Device objects having been created, so we do
            # them separately
            dev._init_interrupts()
            dev._init_gpios()
            dev._init_pwms()
            dev._init_clocks()

    def __repr__(self):
        return "<EDT for '{}', binding directory '{}'>".format(
            self.dts_path, self.bindings_dir)


class Device:
    """
    Represents a device. There's a one-to-one correspondence between device
    tree nodes and Devices.

    These attributes are available on Device objects:

    edt:
      The EDT instance this device is from

    name:
      The name of the device. This is fetched from the node name.

    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

    path:
      The device tree path of the device

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

    parent:
      The parent Device, or None if there is no parent

    enabled:
      True unless the device's node has 'status = "disabled"'

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

    instance_no:
      Dictionary that maps each 'compatible' string for the device to a unique
      index among all devices that have that 'compatible' string.

      As an example, 'instance_no["foo,led"] == 3' can be read as "this is the
      fourth foo,led device".

      Only enabled devices (status != "disabled") are counted. 'instance_no' is
      meaningless for disabled devices.

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

    description:
      The description string from the binding file for the device, or None if
      the device has no binding. Trailing whitespace (including newlines) is
      removed.

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

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

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

    props:
      A dictionary that maps property names to Property objects. Property
      objects are created for all DT properties on the device that are
      mentioned in 'properties:' in the binding.

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

    interrupts:
      A list of Interrupt objects for the interrupts generated by the device

    gpios:
      A dictionary that maps the <prefix> part in '<prefix>-gpios' properties
      to a list of GPIO objects (see the GPIO class).

      For example, 'foo-gpios = <&gpio1 1 2 &gpio2 3 4>' makes gpios["foo"] a
      list of two GPIO objects.

    pwms:
      A list of PWM objects, derived from the 'pwms' property. The list is
      empty if the device has no 'pwms' property.

    clocks:
      A list of Clock objects, derived from the 'clocks' property. The list is
      empty if the device has no 'clocks' property.

    bus:
      The bus for the device as specified in its binding, e.g. "i2c" or "spi".
      None if the binding doesn't specify a bus.

    flash_controller:
      The flash controller for the device. Only meaningful for devices
      representing flash partitions.
    """
    @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))

        addr = _translate(addr, self._node)

        if self.regs and self.regs[0].addr != addr:
            _warn("unit-address and first reg (0x{:x}) don't match for {}"
                  .format(self.regs[0].addr, self.name))

        return addr

    @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 parent(self):
        "See the class docstring"
        return self.edt._node2dev.get(self._node.parent)

    @property
    def enabled(self):
        "See the class docstring"
        return "status" not in self._node.props or \
            self._node.props["status"].to_string() != "disabled"

    @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"
        return _binding_bus(self._binding)

    @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

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

    def __init__(self, edt, node):
        "Private constructor. Not meant to be called by clients."

        # Interrupts, GPIOs, PWMs, and clocks are initialized separately,
        # because they depend on all Devices existing

        self.edt = edt
        self._node = node

        self._init_binding()
        self._init_props()
        self._init_regs()
        self._set_instance_no()

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

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

        if "compatible" in self._node.props:
            self.compats = self._node.props["compatible"].to_strings()
            bus = self._bus_from_parent_binding()

            for compat in self.compats:
                if (compat, bus) in self.edt._compat2binding:
                    # Binding found
                    self.matching_compat = compat
                    self._binding, self.binding_path = \
                        self.edt._compat2binding[compat, bus]

                    self.description = self._binding.get("description")
                    if self.description:
                        self.description = self.description.rstrip()

                    return
        else:
            # No 'compatible' property. See if the parent has a 'sub-node:' key
            # that gives the binding.

            self.compats = []

            if self.parent and self.parent._binding and \
                "sub-node" in self.parent._binding:

                # Binding found
                self._binding = self.parent._binding["sub-node"]
                self.binding_path = self.parent.binding_path

                self.description = self.parent._binding.get("description")
                if self.description:
                    self.description = self.description.rstrip()

                self.matching_compat = self.parent.matching_compat
                return

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

    def _bus_from_parent_binding(self):
        # _init_binding() helper. Returns the bus specified by
        # 'child: bus: ...' in the parent binding, or None if missing.

        if not self.parent:
            return None

        binding = self.parent._binding
        if binding and "child" in binding:
            return binding["child"].get("bus")
        return None

    def _init_props(self):
        # Creates self.props. See the class docstring.

        self.props = {}

        if not self._binding or "properties" not in self._binding:
            return

        for name, options in self._binding["properties"].items():
            self._init_prop(name, options)

    def _init_prop(self, name, options):
        # _init_props() helper for initializing a single property

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

        prop_type = options.get("type")
        if not prop_type:
            _err("'{}' in {} lacks 'type'".format(name, self.binding_path))

        # "Dummy" type for properties like '...-gpios', so that we can require
        # all entries in 'properties:' to have a 'type: ...'. It might make
        # sense to have gpios in 'properties:' for other reasons, e.g. to set
        # 'category: required'.
        if prop_type == "compound":
            return

        val = self._prop_val(name, prop_type,
                             options.get("category") == "optional")
        if val is None:
            # 'category: optional' property that wasn't there
            return

        prop = Property()
        prop.dev = self
        prop.name = name
        prop.description = options.get("description")
        if prop.description:
            prop.description = prop.description.rstrip()
        prop.val = val
        enum = options.get("enum")
        if enum is None:
            prop.enum_index = None
        else:
            if val not in enum:
                _err("value ({}) for property ({}) is not in enumerated "
                     "list {} for node {}".format(val, name, enum, self.name))

            prop.enum_index = enum.index(val)

        self.props[name] = prop

    def _prop_val(self, name, prop_type, optional):
        # _init_prop() helper for getting the property's value

        node = self._node

        if prop_type == "boolean":
            # True/False
            return name in node.props

        prop = node.props.get(name)
        if not prop:
            if not optional and \
                ("status" not in node.props or
                 node.props["status"].to_string() != "disabled"):

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

            return None

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

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

        if prop_type == "uint8-array":
            return prop.value  # Plain 'bytes'

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

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

        _err("'{}' in 'properties:' in {} has unknown type '{}'"
             .format(name, self.binding_path, prop_type))

    def _init_regs(self):
        # Initializes self.regs with a list of Register objects

        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)):
            reg = Register()
            reg.dev = self
            reg.addr = _translate(to_num(raw_reg[:4*address_cells]), node)
            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-names", self.regs)

    def _init_interrupts(self):
        # Initializes self.interrupts with a list of Interrupt objects

        node = self._node

        self.interrupts = []

        for controller_node, spec in _interrupts(node):
            controller = self.edt._node2dev[controller_node]

            interrupt = Interrupt()
            interrupt.dev = self
            interrupt.controller = controller
            interrupt.specifier = self._named_cells(controller, spec, "interrupt")

            self.interrupts.append(interrupt)

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

    def _init_gpios(self):
        # Initializes self.gpios

        self.gpios = {}

        for prefix, gpios in _gpios(self._node).items():
            self.gpios[prefix] = []
            for controller_node, spec in gpios:
                controller = self.edt._node2dev[controller_node]

                gpio = GPIO()
                gpio.dev = self
                gpio.controller = controller
                gpio.specifier = self._named_cells(controller, spec, "GPIOS")
                gpio.name = prefix

                self.gpios[prefix].append(gpio)

    def _init_clocks(self):
        # Initializes self.clocks

        node = self._node

        self.clocks = []

        for controller_node, spec in _clocks(node):
            controller = self.edt._node2dev[controller_node]

            clock = Clock()
            clock.dev = self
            clock.controller = controller
            clock.specifier = self._named_cells(controller, spec, "clocks")
            if "fixed-clock" in controller.compats:
                if "clock-frequency" not in controller.props:
                    _err("{!r} is a 'fixed-clock', but either lacks a "
                         "'clock-frequency' property or does not have "
                         "it specified in its binding".format(controller))

                clock.frequency = controller.props["clock-frequency"].val
            else:
                clock.frequency = None

            self.clocks.append(clock)

        _add_names(node, "clock-names", self.clocks)

    def _init_pwms(self):
        # Initializes self.pwms

        self.pwms = []

        for controller_node, spec in _pwms(self._node):
            controller = self.edt._node2dev[controller_node]

            pwm = PWM()
            pwm.dev = self
            pwm.controller = controller
            pwm.specifier = self._named_cells(controller, spec, "pwms")

            self.pwms.append(pwm)

        _add_names(self._node, "pwm-names", self.pwms)

    def _named_cells(self, controller, spec, controller_s):
        # _init_{interrupts,gpios}() helper. Returns a dictionary that maps
        # #cell names given in the binding for 'controller' to cell values.
        # 'spec' is the raw interrupt/GPIO data, and 'controller_s' a string
        # that gives the context (for error messages).

        if not controller._binding:
            _err("{} controller {!r} for {!r} lacks binding"
                 .format(controller_s, controller._node, self._node))

        if "#cells" in controller._binding:
            cell_names = controller._binding["#cells"]
            if not isinstance(cell_names, list):
                _err("binding for {} controller {!r} has malformed #cells array"
                     .format(controller_s, controller._node))
        else:
            # Treat no #cells in the binding the same as an empty #cells, so
            # that bindings don't have to have an empty #cells for e.g.
            # '#clock-cells = <0>'.
            cell_names = []

        spec_list = to_nums(spec)
        if len(spec_list) != len(cell_names):
            _err("unexpected #cells length in binding for {!r} - {} instead "
                 "of {}".format(controller._node, len(cell_names),
                                len(spec_list)))

        return dict(zip(cell_names, spec_list))

    def _set_instance_no(self):
        # Initializes self.instance_no

        self.instance_no = {}

        for compat in self.compats:
            self.instance_no[compat] = 0
            for other_dev in self.edt.devices:
                if compat in other_dev.compats and other_dev.enabled:
                    self.instance_no[compat] += 1


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

    These attributes are available on Register objects:

    dev:
      The Device 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. 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)
        fields.append("addr: " + hex(self.addr))
        fields.append("size: " + hex(self.size))

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


class Interrupt:
    """
    Represents an interrupt generated by a device.

    These attributes are available on Interrupt objects:

    dev:
      The Device instance that generated the interrupt

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

    controller:
      The Device instance for the controller the interrupt gets sent to. Any
      'interrupt-map' is taken into account, so that this is the final
      controller node.

    specifier:
      A dictionary that maps names from the #cells portion of the binding to
      cell values in the interrupt specifier. 'interrupts = <1 2>' might give
      {"irq": 1, "level": 2}, for example.
    """
    def __repr__(self):
        fields = []

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

        fields.append("target: {}".format(self.controller))
        fields.append("specifier: {}".format(self.specifier))

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


class GPIO:
    """
    Represents a GPIO used by a device.

    These attributes are available on GPIO objects:

    dev:
      The Device instance that uses the GPIO

    name:
      The name of the gpio as extracted out of the "<NAME>-gpios" property. If
      the property is just "gpios" than there is no name.

    controller:
      The Device instance for the controller of the GPIO

    specifier:
      A dictionary that maps names from the #cells portion of the binding to
      cell values in the gpio specifier. 'foo-gpios = <&gpioc 5 0>' might give
      {"pin": 5, "flags": 0}, for example.
    """
    def __repr__(self):
        fields = []

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

        fields.append("target: {}".format(self.controller))
        fields.append("specifier: {}".format(self.specifier))

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


class Clock:
    """
    Represents a clock used by a device.

    These attributes are available on Clock objects:

    dev:
      The Device instance that uses the clock

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

    controller:
      The Device instance for the controller of the clock.

    frequency:
      The frequency of the clock for fixed clocks ('fixed-clock' in
      'compatible'), as an integer. Derived from the 'clock-frequency'
      property. None if the clock is not a fixed clock.

    specifier:
      A dictionary that maps names from the #cells portion of the binding to
      cell values in the clock specifier
    """
    def __repr__(self):
        fields = []

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

        if self.frequency is not None:
            fields.append("frequency: {}".format(self.frequency))

        fields.append("target: {}".format(self.controller))
        fields.append("specifier: {}".format(self.specifier))

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


class PWM:
    """
    Represents a PWM used by a device.

    These attributes are available on PWM objects:

    dev:
      The Device instance that uses the PWM

    name:
      The name of the pwm as given in the 'pwm-names' property, or the
      node name if the 'pwm-names' property doesn't exist.

    controller:
      The Device instance for the controller of the PWM

    specifier:
      A dictionary that maps names from the #cells portion of the binding to
      cell values in the pwm specifier. 'pwms = <&pwm 0 5000000>' might give
      {"channel": 0, "period": 5000000}, for example.
    """
    def __repr__(self):
        fields = []

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

        fields.append("target: {}".format(self.controller))
        fields.append("specifier: {}".format(self.specifier))

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


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

    Only properties mentioned in 'properties:' get created.

    These attributes are available on Property objects:

    dev:
      The Device instance the property is on

    name:
      The name of the property

    description:
      The description string from the property as given in the binding, or None
      if missing. Trailing whitespace (including newlines) is removed.

    val:
      The value of the property, with the format determined by the 'type:'
      key from the binding

    enum_index:
      The index of the property's value in the 'enum:' list in the binding, or
      None if the binding has no 'enum:'
    """
    def __repr__(self):
        fields = ["name: " + self.name,
                  # repr() to deal with lists
                  "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 EDTError(Exception):
    "Exception raised for Extended Device Tree-related errors"


#
# Public global functions
#


def spi_dev_cs_gpio(dev):
    # Returns an SPI device's GPIO chip select if it exists, as a GPIO
    # instance, and None otherwise. See
    # Documentation/devicetree/bindings/spi/spi-bus.txt in the Linux kernel.

    if dev.bus == "spi" and dev.parent:
        parent_cs = dev.parent.gpios.get("cs")
        if parent_cs:
            # cs-gpios is indexed by the unit address
            cs_index = dev.regs[0].addr
            if cs_index >= len(parent_cs):
                _err("index from 'regs' in {!r} ({}) is >= number of cs-gpios "
                     "in {!r} ({})".format(
                         dev, cs_index, dev.parent, len(parent_cs)))

            return parent_cs[cs_index]

    return None


#
# Private global functions
#


def _dt_compats(dt):
    # Returns a set() with all 'compatible' strings in the device tree
    # 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_dir):
    # Returns a list with the paths to all bindings (.yaml files) in
    # 'bindings_dir'

    return [os.path.join(root, filename)
            for root, _, filenames in os.walk(bindings_dir)
                for filename in filenames
                    if filename.endswith(".yaml")]


def _binding_compat(binding_path):
    # Returns the compatible string specified in the binding at 'binding_path'.
    # Uses a regex to avoid having to parse the bindings, which is slow when
    # done for all bindings.

    with open(binding_path) as binding:
        for line in binding:
            match = re.match(r'\s+constraint:\s*"([^"]*)"', line)
            if match:
                return match.group(1)

    return None


def _binding_bus(binding):
    # Returns the bus specified in 'binding' (the bus the device described by
    # 'binding' is on), e.g. "i2c", or None if 'binding' is None or doesn't
    # specify a bus

    if binding and "parent" in binding:
        return binding["parent"].get("bus")
    return None


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

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


def _load_binding(path):
    # Loads a top-level binding .yaml file from 'path', also handling any
    # !include'd files. Returns the parsed PyYAML output (Python
    # lists/dictionaries/strings/etc. representing the file).

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


def _merge_included_bindings(binding, binding_path):
    # Merges any bindings in the 'inherits:' section of 'binding' into the top
    # level of 'binding'. !includes have already been processed at this point,
    # and leave the data for the included binding(s) in 'inherits:'.
    #
    # Properties in 'binding' take precedence over properties from included
    # bindings.

    # Currently, we require that each !include'd file is a well-formed
    # binding in itself
    _check_binding(binding, binding_path)

    if "inherits" in binding:
        for inherited in binding.pop("inherits"):
            _merge_props(
                binding, _merge_included_bindings(inherited, binding_path),
                None, binding_path)

    return binding


def _merge_props(to_dict, from_dict, parent, binding_path):
    # Recursively merges 'from_dict' into 'to_dict', to implement !include. If
    # a key exists in both 'from_dict' and 'to_dict', then 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)
        elif prop not in to_dict:
            to_dict[prop] = from_dict[prop]
        elif _bad_overwrite(to_dict, from_dict, prop):
            _err("{} (in '{}'): '{}' from !included file overwritten "
                 "('{}' replaced with '{}')".format(
                     binding_path, parent, prop, from_dict[prop],
                     to_dict[prop]))


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

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

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

    # Allow a property to be made required when it previously was optional
    # without a warning
    if prop == "category" and to_dict["category"] == "required" and \
                              from_dict["category"] == "optional":
        return False

    return True


def _check_binding(binding, binding_path):
    # Does sanity checking on 'binding'

    for prop in "title", "description":
        if prop not in binding:
            _err("missing '{}' property in {}".format(prop, binding_path))

    for prop in "title", "description":
        if not isinstance(binding[prop], str) or not binding[prop]:
            _err("missing, malformed, or empty '{}' in {}"
                 .format(prop, binding_path))

    ok_top = {"title", "description", "inherits", "properties", "#cells",
              "parent", "child", "sub-node"}

    for prop in binding:
        if prop not in ok_top:
            _err("unknown key '{}' in {}, expected one of {}"
                 .format(prop, binding_path, ", ".join(ok_top)))

    for pc in "parent", "child":
        if pc in binding:
            # Just 'bus:' is expected at the moment
            if binding[pc].keys() != {"bus"}:
                _err("expected (just) 'bus:' in '{}:' in {}"
                     .format(pc, binding_path))

            if not isinstance(binding[pc]["bus"], str):
                _err("malformed '{}: bus:' value in {}, expected string"
                     .format(pc, binding_path))

    # Check properties

    if "properties" not in binding:
        return

    ok_prop_keys = {"description", "type", "category", "constraint", "enum"}
    ok_categories = {"required", "optional"}

    for prop, keys in binding["properties"].items():
        for key in keys:
            if key not in ok_prop_keys:
                _err("unknown setting '{}' in 'properties: {}: ...' in {}, "
                     "expected one of {}".format(
                         key, prop, binding_path, ", ".join(ok_prop_keys)))

        if "category" in keys and keys["category"] not in ok_categories:
            _err("unrecognized category '{}' for '{}' in 'properties' in {}, "
                 "expected one of {}".format(
                     keys["category"], prop, binding_path,
                     ", ".join(ok_categories)))

        if "description" in keys and not isinstance(keys["description"], str):
            _err("missing, malformed, or empty 'description' for '{}' in "
                 "'properties' in {}".format(prop, binding_path))


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.

    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):
        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:
    #   Device tree node
    #
    # names-ident:
    #   name of property holding names, e.g. "reg-names"
    #
    # objs:
    #   list of objects whose .name field should be set

    if names_ident in node.props:
        names = node.props[names_ident].to_strings()
        if len(names) != len(objs):
            _err("{} property in {} has {} strings, expected {} strings"
                 .format(names_ident, node.name, len(names), len(objs)))

        for obj, name in zip(objs, names):
            obj.name = name
    else:
        for obj in objs:
            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>, <specifier>) tuples, with one tuple per
    # interrupt generated by 'node'. <controller> is the destination of the
    # interrupt (possibly after mapping through an 'interrupt-map'), and
    # <specifier> 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_cells)]

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

    return []


def _map_interrupt(child, parent, child_spec):
    # Translates an interrupt headed from 'child' to 'parent' with specifier
    # 'child_spec' through any 'interrupt-map' properties. Returns a
    # (<controller>, <specifier>) 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 4*(own_address_cells(node) + _interrupt_cells(node))

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

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


def _clocks(node):
    # Returns a list of (<controller>, <specifier>) tuples for any 'clocks'
    # property on 'node', or an empty list if 'node' has no 'clocks'.
    # <controller> is a dtlib.Node.

    if "clocks" not in node.props:
        return []
    return _phandle_val_list(node.props["clocks"], _clock_cells)


def _pwms(node):
    # Returns a list of (<controller>, <specifier>) tuples for any 'pwms'
    # property on 'node', or an empty list if 'node' has no 'pwms'.
    # <controller> is a dtlib.Node.

    if "pwms" not in node.props:
        return []
    return _phandle_val_list(node.props["pwms"], _pwm_cells)


def _gpios(node):
    # Returns a dictionary that maps '<prefix>-gpios' prefixes to lists of
    # (<controller>, <specifier>) tuples (possibly after mapping through an
    # gpio-map). <controller> is a dtlib.Node.

    res = {}

    for name, prop in node.props.items():
        if name.endswith("gpios"):
            # Get the prefix from the property name:
            #   - gpios     -> "" (deprecated, should have a prefix)
            #   - foo-gpios -> "foo"
            #   - etc.
            prefix = name[:-5]
            if prefix.endswith("-"):
                prefix = prefix[:-1]

            res[prefix] = [
                _map_gpio(prop.node, controller, spec)
                for controller, spec in _phandle_val_list(prop, _gpio_cells)
            ]

    return res


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

    if "gpio-map" not in parent.props:
        return (parent, child_spec)

    return _map("gpio", child, parent, child_spec,
                lambda node: 4*_gpio_cells(node))


def _map(prefix, child, parent, child_spec, spec_len_fn):
    # 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 its
    #   *-cells value, e.g. #interrupt-cells

    map_prop = parent.props.get(prefix + "-map")
    if not map_prop:
        if 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 specifier"
                 .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 " + repr(map_prop))

        map_parent_spec_len = spec_len_fn(map_parent)
        if len(raw) < map_parent_spec_len:
            _err("bad value for {!r}, missing/truncated parent specifier"
                 .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 specifier.
        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)

    _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 specifier 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_fn):
    # Parses a '<phandle> <value> <phandle> <value> ...' value
    #
    # prop:
    #   dtlib.Property with value to parse
    #
    # cells_fn:
    #   A function that returns the number of cells for a <value>. Takes the
    #   node pointed at by the preceding <phandle> as its argument.
    #
    # Returns a list of (<node>, <value>) tuples, where <node> is the node
    # pointed at by <phandle>. 'cells_fn' is a function called on <node> to get
    # the number of cells for <value>.

    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:
            _err("bad phandle in " + repr(prop))

        n_cells = n_cells_fn(node)
        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 _gpio_cells(node):
    if "#gpio-cells" not in node.props:
        _err("{!r} lacks #gpio-cells".format(node))
    return node.props["#gpio-cells"].to_num()


def _pwm_cells(node):
    if "#pwm-cells" not in node.props:
        _err("{!r} lacks #pwm-cells".format(node))
    return node.props["#pwm-cells"].to_num()


def _clock_cells(node):
    if "#clock-cells" not in node.props:
        _err("{!r} lacks #clock-cells".format(node))
    return node.props["#clock-cells"].to_num()


def _slice(node, prop_name, size):
    # 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'.

    raw = node.props[prop_name].value
    if len(raw) % size:
        _err("'{}' property in {!r} has length {}, which is not evenly "
             "divisible by {}".format(prop_name, node, len(raw), size))

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


def _err(msg):
    raise EDTError(msg)


def _warn(msg):
    print("warning: " + msg, file=sys.stderr)
