\documentclass[aspectratio=169,obeyspaces,spaces,hyphens,dvipsnames]{beamer}
\usepackage[utf8]{inputenc}
\usepackage{lmodern}% http://ctan.org/pkg/lm
\usepackage{minted}
\usepackage{hyperref}
\usepackage{xcolor}
\usepackage{pgfplots}
\usepackage{tikz}
\usepackage[normalem]{ulem}

\mode<presentation>
\usetheme{Bootlin}

\def\signed #1{{\leavevmode\unskip\nobreak\hfil\penalty50\hskip2em
  \hbox{}\nobreak\hfil(#1)
  \parfillskip=0pt \finalhyphendemerits=0 \endgraf}}

\newsavebox\mybox
\newenvironment{aquote}[1]
  {\savebox\mybox{#1}\begin{quotation}}
  {\signed{\usebox\mybox}\end{quotation}}

\title{Title}
\authors{Thomas Petazzoni}
\email{thomas.petazzoni@bootlin.com}
\slidesurl{https://bootlin.com/pub/conferences/2020/lee/petazzoni-dt-hw-description-everybody}
\institute{Bootlin}
\conference{Embedded Live Event}

\begin{document}

\addtocontents{toc}{\protect\setcounter{tocdepth}{-1}}
\section{Device Tree: hardware description for everybody!}
\addtocontents{toc}{\protect\setcounter{tocdepth}{2}}

\begin{frame}{Thomas Petazzoni}
  \begin{columns}
    \column{0.6\textwidth}
    \begin{itemize}
    \item 12+ years CTO/Embedded Linux engineer at Bootlin
      \begin{itemize}
      \item Embedded Linux {\bf expertise}
      \item {\bf Development}, consulting and training
      \item Bootloader, Linux kernel, Yocto Project, Buildroot
      \item Complete Linux BSP development
      \item Hardware support in bootloader/Linux
      \item Strong open-source focus: upstreaming and contributions
      \item Freely available training materials
      \end{itemize}
    \item Co-maintainer of {\bf Buildroot}
    \item Living in {\bf Toulouse}, France
    \end{itemize}
    \column{0.3\textwidth}
    \includegraphics[width=\textwidth]{common/bootlin-logo.pdf}

    \vspace{1.5cm}

    \includegraphics[width=\textwidth]{windsurf.jpg}
  \end{columns}
\end{frame}

\begin{frame}{Agenda}
  \begin{itemize}
  \item This talk is an update from the {\em Device Tree for Dummies}
    talk given in 2013/2014
  \item Why the Device Tree ?
  \item Basic Device Tree syntax
  \item Device Tree inheritance
  \item Device Tree specifications and bindings
  \item Building and validating Device Trees
  \item Common properties and examples
  \end{itemize}
\end{frame}

\begin{frame}{Your typical embedded platform}
  \begin{center}
    \includegraphics[height=0.8\textheight]{hardware.pdf}
  \end{center}
\end{frame}

\begin{frame}{Discoverable vs. non-discoverable hardware}
  \begin{itemize}
  \item Some hardware busses provide {\bf discoverability} mechanisms
    \begin{itemize}
    \item E.g: PCI(e), USB
    \item One does not need to know ahead of time what will be
      connected on these busses
    \item Devices can be enumerated and identified at runtime
    \item Concept of {\em vendor ID}, {\em product ID}, {\em device
        class}, etc.
    \end{itemize}
  \item But many hardware busses {\bf do not provide discoverability}
    mechanisms
    \begin{itemize}
    \item E.g: I2C, SPI, 1-wire, memory-mapped, etc.
    \item One needs to know what is connected on those busses, and how
      they are connected to the rest of the system
    \item Embedded systems typically make extensive use of such busses
    \end{itemize}
  \end{itemize}
\end{frame}

\begin{frame}{Hardware description for non-discoverable hardware}
  Allows the operating system or bootloader to {\bf know things like}:
  \begin{itemize}
  \item This {\bf system-on-chip} has:
    \begin{itemize}
    \item 2 Cortex-A9 CPU cores
    \item 2 memory-mapped UART controllers of {\em this} variant, one
      with registers at \code{0xF1000000} and IRQ {\em 23}, and another
      with registers at \code{0xF1001000} and IRQ {\em 24}
    \item 3 I2C controllers of {\em that} variant, with registers at
      {\em those} memory-mapped addresses, {\em those} IRQs and taking
      their input clock from {\em this} source
    \end{itemize}
  \item This {\bf board} has an CS4234 audio codec
    \begin{itemize}
    \item Connected on the I2C bus 0 of the SoC, at slave address {\em
        0x45}
    \item Connected to the I2S interface 2 of the SoC, with the codec
      providing the clocks
    \item With its reset signal connected to GPIO {\em 67} of the SoC
    \end{itemize}
  \end{itemize}
  These details {\bf cannot be guessed} by the operating
  system/bootloader.
\end{frame}

\begin{frame}{Describing non-discoverable hardware}
  \begin{itemize}
  \item Directly in the {\bf OS/bootloader code}, using compiled data
    structures, typically in C
    \begin{itemize}
    \item How it was done on most embedded platforms in Linux, U-Boot.
    \item Considered not maintainable/sustainable on ARM32, which
      motivated the move to another solution.
    \end{itemize}
  \item Using {\bf ACPI} tables
    \begin{itemize}
    \item On {\em x86} systems, but also on a subset of ARM64 platforms
    \item Tables provided by the firmware
    \end{itemize}
  \item Using a {\bf Device Tree}
    \begin{itemize}
    \item On most embedded-oriented CPU architectures that run Linux:
      ARC, ARM64, RISC-V, ARM32, PowerPC, Xtensa, MIPS, etc.
    \item Originates from the PowerPC world, not Linux specific
    \item Now used by Linux, U-Boot, Barebox, TF-A, FreeBSD, etc.
    \item Writing/tweaking a DT is now always necessary when porting
      Linux to a new board.
    \item The topic of this talk !
    \end{itemize}
  \end{itemize}
\end{frame}

\begin{frame}{Device Tree: principle}
  \begin{itemize}
  \item A tree data structure describing the hardware is written by a
    developer in a {\em Device Tree Source} file, \code{.dts}
  \item Gets compiled to a more efficient {\em Device Tree Blob}
    representation, \code{.dtb} by the {\em Device Tree Compiler},
    \code{dtc}
  \item The resulting \code{.dtb} accurately describes the hardware
    platform in an {\bf OS-agnostic} way and:
    \begin{itemize}
    \item Can be {\bf linked directly} inside a bootloader binary
      (U-Boot, Barebox)
    \item Can be {\bf passed} to the operating system by the
      bootloader (Linux)
    \item U-Boot: \code{bootz <kernel-addr> - <dtb-addr>}
    \end{itemize}
  \end{itemize}
\end{frame}

\begin{frame}{Base syntax}
  \begin{columns}
    \column{0.3\textwidth}
    \begin{itemize}
    \item Tree of {\bf nodes}
    \item Nodes with {\bf properties}
    \item A node $\approx$ a device or IP block
    \item Properties $\approx$ device characteristics
    \item \code{dtc} only does syntax checking, no semantic validation
    \end{itemize}
    \column{0.7\textwidth}
    \begin{center}
      \includegraphics[height=0.6\textheight]{dt-basic-syntax.pdf}
    \end{center}
  \end{columns}
\end{frame}

\begin{frame}[fragile]{Simplified example}
  \begin{columns}
    \column{0.6\textwidth}
    \begin{onlyenv}<1>
      \begin{block}{}
\begin{minted}[fontsize=\tiny]{perl}
/ {
   #address-cells = <1>;
   #size-cells = <1>;
   compatible = "vendor1,board", "vendor2,soc";

   cpus { ... };
   memory@0 { ... };
   chosen { ... };
   soc {
      intc: interrupt-controller@f8f01000 { ... };
      i2c0: i2c@e0004000 { ... };
      usb0: usb@e0002000 { ... };
   };
};
\end{minted}
      \end{block}
    \end{onlyenv}
    \begin{onlyenv}<2>
      \begin{block}{}
\begin{minted}[fontsize=\tiny]{perl}
/ {
   cpus {
     #address-cells = <1>;
     #size-cells = <0>;

     cpu0: cpu@0 {
         compatible = "arm,cortex-a9";
         device_type = "cpu";
         reg = <0>;
     };

     cpu1: cpu@1 {
         compatible = "arm,cortex-a9";
         device_type = "cpu";
         reg = <1>;
     };
   };

   memory@0 { ... };
   chosen { ... };
   soc {
      intc: interrupt-controller@f8f01000 { ... };
      i2c0: i2c@e0004000 { ... };
      usb0: usb@e0002000 { ... };
   };
};
\end{minted}
      \end{block}
    \end{onlyenv}
    \begin{onlyenv}<3>
      \begin{block}{}
\begin{minted}[fontsize=\tiny]{perl}
/ {
   cpus { ... };
   memory@0 {
       device_type = "memory";
       reg = <0x0 0x20000000>;
   };

   chosen {
       bootargs = "";
       stdout-path = "serial0:115200n8";
   };

   soc {
      intc: interrupt-controller@f8f01000 { ... };
      i2c0: i2c@e0004000 { ... };
      usb0: usb@e0002000 { ... };
   };
};
\end{minted}
      \end{block}
    \end{onlyenv}
    \begin{onlyenv}<4>
      \begin{block}{}
\begin{minted}[fontsize=\tiny]{perl}
/ {
   cpus { ... };
   memory@0 { ... };
   chosen { ... };

   soc {
      compatible = "simple-bus";
      #address-cells = <1>;
      #size-cells = <1>;
      interrupt-parent = <&intc>;

      intc: interrupt-controller@f8f01000 {
              compatible = "arm,cortex-a9-gic";
              #interrupt-cells = <3>;
              interrupt-controller;
              reg = <0xF8F01000 0x1000>,
                    <0xF8F00100 0x100>;
      };

      i2c0: i2c@e0004000 { ... };
      usb0: usb@e0002000 { ... };
   };
};
\end{minted}
      \end{block}
    \end{onlyenv}
    \begin{onlyenv}<5>
      \begin{block}{}
\begin{minted}[fontsize=\tiny]{perl}
/ {
   cpus { ... };
   memory@0 { ... };
   chosen { ... };

   soc {
      intc: interrupt-controller@f8f01000 { ... };

      i2c0: i2c@e0004000 {
              compatible = "cdns,i2c-r1p10";
              status = "okay";
              clocks = <&clkc 38>;
              interrupts = <GIC_SPI 25 IRQ_TYPE_LEVEL_HIGH>;
              reg = <0xe0004000 0x1000>;
              #address-cells = <1>;
              #size-cells = <0>;
              clock-frequency = <400000>;

              eeprom0: eeprom@52 {
                   compatible = "atmel,24c02";
                   reg = <0x52>;
              };
      };

      usb0: usb@e0002000 { ... };
   };
};
\end{minted}
      \end{block}
    \end{onlyenv}
    \begin{onlyenv}<6>
      \begin{block}{}
\begin{minted}[fontsize=\tiny]{perl}
/ {
   cpus { ... };
   memory@0 { ... };
   chosen { ... };

   soc {
      compatible = "simple-bus";
      #address-cells = <1>;
      #size-cells = <1>;
      interrupt-parent = <&intc>;

      intc: interrupt-controller@f8f01000 { ... };
      i2c0: i2c@e0004000 { ... };

      usb0: usb@e0002000 {
              compatible = "xlnx,zynq-usb-2.20a", "chipidea,usb2";
              status = "okay";
              clocks = <&clkc 28>;
              interrupt-parent = <&intc>;
              interrupts = <GIC_SPI 21 IRQ_TYPE_LEVEL_HIGH>;
              reg = <0xe0002000 0x1000>;
              phy_type = "ulpi";
              dr_mode = "host";
              usb-phy = <&usb_phy0>;
      };
   };
};
\end{minted}
      \end{block}
    \end{onlyenv}
    \column{0.4\textwidth}
    \includegraphics[width=\textwidth]{simple-hardware.pdf}
  \end{columns}
\end{frame}

\begin{frame}{Where are Device Tree Sources located ?}
  \begin{itemize}
  \item Even though they are OS-agnostic, no central and OS-neutral
    place to host Device Tree sources and share them between projects
    \begin{itemize}
    \item Often discussed, never done
    \end{itemize}
  \item In practice, the Linux kernel sources can be considered as the
    canonical location for Device Tree Source files
    \begin{itemize}
    \item \code{arch/<ARCH>/boot/dts}
    \item $\approx$ 4700 Device Tree Source files in Linux as of 5.10
    \end{itemize}
  \item Duplicated/synced in various projects
    \begin{itemize}
    \item U-Boot, Barebox
    \end{itemize}
  \end{itemize}
\end{frame}

\begin{frame}[fragile]{Device Tree inheritance}
  \begin{itemize}
  \item Device Tree files are not monolithic, they can be split in
    several files, including each other.
  \item \code{.dtsi} files are included files, while \code{.dts} files
    are {\em final} Device Trees
    \begin{itemize}
    \item Only \code{.dts} files are accepted as input to \code{dtc}
    \end{itemize}
  \item Typically, \code{.dtsi} will contain definition of SoC-level
    information (or sometimes definitions common to several almost
    identical boards)
  \item The \code{.dts} file contains the board-level information
  \item The inclusion works by {\bf overlaying} the tree of the
    including file over the tree of the included file.
  \item Uses the C pre-processor \code{#include} directive
    \begin{itemize}
    \item Using the C pre-processor also allows to use \code{#define}
      to replace hardcoded values by human readable definitions
    \end{itemize}
  \end{itemize}
\end{frame}

\begin{frame}{Device Tree inheritance example}
  \begin{center}
    \includegraphics[height=0.8\textheight]{dt-inheritance.pdf}
  \end{center}
\end{frame}

\begin{frame}[fragile]{Building Device Trees in Linux}
  \begin{itemize}
  \item On ARM/ARM64, \code{arch/<ARCH>/boot/dts/Makefile} or
    \code{arch/<ARCH>/boot/dts/<vendor>/Makefile} indicates which DT
    to build depending on the platform
    \begin{block}{arch/arm64/boot/dts/marvell/Makefile}
\begin{verbatim}
dtb-$(CONFIG_ARCH_MVEBU) += armada-3720-db.dtb
dtb-$(CONFIG_ARCH_MVEBU) += armada-3720-espressobin.dtb
\end{verbatim}
    \end{block}
  \item Building the kernel with \code{make} will also build the
    Device Trees on most architectures
  \item Explicit \code{make dtbs} target also available
    \begin{block}{}
\begin{verbatim}
   DTC  armada-3720-db.dtb
   DTC  armada-3720-espressobin.dtb
\end{verbatim}
    \end{block}
  \end{itemize}
\end{frame}

\begin{frame}{Validating Device Tree in Linux}
  \begin{itemize}
  \item \code{dtc} only does syntaxic validation
  \item YAML bindings allow to do semantic validation
    \begin{itemize}
    \item \code{make dt_bindings_check}\\
      verify that YAML bindings are valid
    \item \code{make dtbs_check}\\
      validate DTs currently enabled against YAML bindings
    \end{itemize}
  \end{itemize}
\end{frame}

\begin{frame}[fragile]{Exploring the DT on the target}
  \begin{itemize}
  \item In \code{/sys/firmware/devicetree/base}, there is a
    directory/file representation of the Device Tree contents
{\footnotesize
    \begin{block}{}
\begin{verbatim}
# ls -l /sys/firmware/devicetree/base/
total 0
-r--r--r--    1 root     root     4 Jan  1 00:00 #address-cells
-r--r--r--    1 root     root     4 Jan  1 00:00 #size-cells
drwxr-xr-x    2 root     root     0 Jan  1 00:00 chosen
drwxr-xr-x    3 root     root     0 Jan  1 00:00 clocks
-r--r--r--    1 root     root    34 Jan  1 00:00 compatible
[...]
-r--r--r--    1 root     root     1 Jan  1 00:00 name
drwxr-xr-x   10 root     root     0 Jan  1 00:00 soc
\end{verbatim}
    \end{block}
}
  \item If \code{dtc} is available on the target, possible to "unpack"
    the Device Tree using:\\
    \code{dtc -I fs /sys/firmware/devicetree/base}
  \end{itemize}
\end{frame}

\begin{frame}{Modifying the Device Tree at runtime}
  \begin{itemize}
  \item U-Boot automatically patches the {\em Device Tree Blob} passed
    to Linux
    \begin{itemize}
    \item Sets the RAM base address and size
    \item Sets the kernel command line
    \item Sets MAC address for network interfaces
    \end{itemize}
  \item Additional {\em Device Tree Blob} patching in U-Boot can be
    done
    \begin{itemize}
    \item Using \code{fdt} commands: \code{fdt set}, \code{fdt
        mknode}, \code{fdt rm}
    \item Using {\em Device Tree Overlays}
    \end{itemize}
  \end{itemize}
\end{frame}

\begin{frame}{Device Tree Overlays}
  \begin{itemize}
  \item A number of platforms have some flexibility aspects that are
    difficult to describe in a static Device Tree
    \begin{itemize}
    \item Base boards to which an arbitrary number of expansion boards
      can be connected: BeagleBoard capes, RaspberrPi hats, etc.
    \item FPGA with arbitrary IP blocks synthetized
    \end{itemize}
  \item A {\em Device Tree Overlay} is a small snippet of Device Tree
    that acts as a {\em patch} to a Device Tree
    \begin{itemize}
    \item For example to describe additional devices provided by an
      expansion board
    \end{itemize}
  \item U-Boot supports applying DT overlays
  \item No support in Linux for applying DT overlays however
  \item Examples:
    \url{https://github.com/raspberrypi/linux/tree/rpi-5.4.y/arch/arm/boot/dts/overlays/}
  \end{itemize}
\end{frame}

\begin{frame}{Device Tree specifications}
  \begin{columns}
    \column{0.7\textwidth}
    \begin{itemize}
    \item How does one know how to write the correct nodes/properties to
      describe a given hardware platform~?
    \item The {\bf DeviceTree Specifications} at
      \url{https://www.devicetree.org/specifications/} gives the base
      Device Tree syntax and specifies a number of standard
      properties.
      \begin{itemize}
      \item Far from being sufficient, though.
      \end{itemize}
    \item The {\bf Device Tree Bindings} are documents that each
      describe how a particular piece of hardware.
      \begin{itemize}
      \item \code{Documentation/devicetree/bindings/} in Linux kernel sources
      \item Reviewed by DT bindings maintainer team
      \item Legacy: human readable documents
      \item New norm: YAML-written specifications
      \end{itemize}
    \end{itemize}
    \column{0.3\textwidth}
    \includegraphics[width=\textwidth]{dt-spec.png}
  \end{columns}
\end{frame}

\begin{frame}[fragile]{Device Tree binding: old style}
  \begin{columns}[t]
    \column{0.5\textwidth}
    \begin{block}{}
      {\fontsize{5}{6}\selectfont
\begin{verbatim}
I2C for Atmel platforms

Required properties :
- compatible : Must be one of:
        "atmel,at91rm9200-i2c",
        "atmel,at91sam9261-i2c",
        "atmel,at91sam9260-i2c",
        "atmel,at91sam9g20-i2c",
        "atmel,at91sam9g10-i2c",
        "atmel,at91sam9x5-i2c",
        "atmel,sama5d4-i2c",
        "atmel,sama5d2-i2c",
        "microchip,sam9x60-i2c".
- reg: physical base address of the controller and length of memory mapped
     region.
- interrupts: interrupt number to the cpu.
- #address-cells = <1>;
- #size-cells = <0>;
- clocks: phandles to input clocks.

Optional properties:
- clock-frequency: Desired I2C bus frequency in Hz, otherwise defaults
  to 100000
- dmas: A list of two dma specifiers, one for each entry in
  dma-names.
- dma-names: should contain "tx" and "rx".
- scl-gpios: specify the gpio related to SCL pin
- sda-gpios: specify the gpio related to SDA pin
[...]

\end{verbatim}
      }
    \end{block}
    \column{0.5\textwidth}
    \begin{block}{}
      {\fontsize{5}{6}\selectfont
\begin{verbatim}
Examples :

i2c0: i2c@fff84000 {
        compatible = "atmel,at91sam9g20-i2c";
        reg = <0xfff84000 0x100>;
        interrupts = <12 4 6>;
        #address-cells = <1>;
        #size-cells = <0>;
        clocks = <&twi0_clk>;
        clock-frequency = <400000>;

        24c512@50 {
                compatible = "atmel,24c512";
                reg = <0x50>;
                pagesize = <128>;
        }
}
\end{verbatim}
      }
    \end{block}
  \end{columns}
\end{frame}

\begin{frame}[fragile]{Device Tree binding: YAML style}
  \begin{columns}[t]
    \column{0.5\textwidth}
    \begin{block}{}
      {\fontsize{5}{6}\selectfont
\begin{minted}{yaml}
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
# Copyright 2019 BayLibre, SAS
%YAML 1.2
---
$id: "http://devicetree.org/schemas/i2c/amlogic,meson6-i2c.yaml#"
$schema: "http://devicetree.org/meta-schemas/core.yaml#"

title: Amlogic Meson I2C Controller

maintainers:
  - Neil Armstrong <narmstrong@baylibre.com>
  - Beniamino Galvani <b.galvani@gmail.com>

allOf:
  - $ref: /schemas/i2c/i2c-controller.yaml#

properties:
  compatible:
    enum:
      - amlogic,meson6-i2c # Meson6, Meson8 and compatible SoCs
      - amlogic,meson-gxbb-i2c # GXBB and compatible SoCs

  reg:
    maxItems: 1

  interrupts:
    maxItems: 1
\end{minted}
      }
    \end{block}
    \column{0.5\textwidth}
    \begin{block}{}
      {\fontsize{5}{6}\selectfont
\begin{minted}{yaml}
  clocks:
    minItems: 1

required:
  - compatible
  - reg
  - interrupts
  - clocks

unevaluatedProperties: false

examples:
  - |
    i2c@c8100500 {
        compatible = "amlogic,meson6-i2c";
        reg = <0xc8100500 0x20>;
        interrupts = <92>;
        clocks = <&clk81>;
        #address-cells = <1>;
        #size-cells = <0>;

        eeprom@52 {
            compatible = "atmel,24c32";
            reg = <0x52>;
        };
    };
\end{minted}
      }
    \end{block}
  \end{columns}
\end{frame}

\begin{frame}{Device Tree design principles}
  \begin{itemize}
  \item Describe hardware (how the hardware is), not configuration
    (how I choose to use the hardware)
  \item OS-agnostic
    \begin{itemize}
    \item For a given piece of HW, Device Tree should be the same for
      U-Boot, FreeBSD or Linux
    \item There should be no need to change the Device Tree when updating the OS
    \end{itemize}
  \item Describe integration of hardware components, not the internals
    of hardware components
    \begin{itemize}
    \item The details of how a specific device/IP block is working is
      handled by code in device drivers
    \item The Device Tree describes how the device/IP block is
      connected/integrated with the rest of the system: IRQ lines, DMA
      channels, clocks, reset lines, etc.
    \end{itemize}
  \item Like all beautiful design principles, these principles are not
    sometimes violated.
  \end{itemize}
\end{frame}

\begin{frame}{The {\tt compatible} property}
  \begin{itemize}
  \item Is a list of strings
    \begin{itemize}
    \item From the most specific to the less specific
    \end{itemize}
  \item Describes the specific binding to which the node complies.
  \item It uniquely identifies the {\em programming model} of the
    device.
  \item Practically speaking, it is used by the operating system to
    find the appropriate driver for this device.
  \item Special value: \code{simple-bus} indicates a bus where all
    sub-nodes are memory-mapped devices. Generally used for devices
    inside the SoC.
  \item When describing real hardware, typical form is
    \code{vendor,model}
  \item Examples:
    \begin{itemize}
    \item \code{compatible = "arm,armv8-timer";}
    \item \code{compatible = "actions,s900-uart", "actions,owl-uart";}
    \item \code{compatible = "regulator-fixed";}
    \item \code{compatible = "gpio-keys";}
    \end{itemize}
  \end{itemize}
\end{frame}

\begin{frame}[fragile]{Matching with drivers in Linux: platform driver}
  \begin{block}{drivers/tty/serial/imx.c}
    {\tiny
  \begin{minted}{c}
static const struct of_device_id imx_uart_dt_ids[] = {
        { .compatible = "fsl,imx6q-uart", .data = ... },
        { .compatible = "fsl,imx53-uart", .data = ... },
        { .compatible = "fsl,imx1-uart", .data = ... },
        { .compatible = "fsl,imx21-uart", .data = ... },
        { /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, imx_uart_dt_ids);

static struct platform_driver imx_uart_platform_driver = {
        .probe = imx_uart_probe,
        .remove = imx_uart_remove,

        .id_table = imx_uart_devtype,
        .driver = {
                .name = "imx-uart",
                .of_match_table = imx_uart_dt_ids,
                .pm = &imx_uart_pm_ops,
        },
};
\end{minted}
    }
  \end{block}
\end{frame}

\begin{frame}{Common properties}
  \begin{itemize}
  \item \code{reg}
    \begin{itemize}
    \item Memory-mapped devices: base address and size of the
      registers. Can have several entries.
    \item I2C devices: address on the I2C bus
    \item SPI devices: chip select number
    \end{itemize}
  \item \code{interrupts}, \code{interrupt-parent},
    \code{interrupts-extended}: interrupts lines used by the device,
    and which interrupt controller they are connected to.
  \item \code{clocks}: which clock(s) are used by the device, from
    which clock controller
  \item \code{dmas}: which DMA controller and channels are used by the
    device
  \item \code{status}: \code{okay} means the device is present and
    should be enabled, otherwise, the device is left unused
  \item \code{pinctrl-*}: indicates the pin-muxing configuration
    requested by the device
  \end{itemize}
\end{frame}

\begin{frame}[fragile]{Cells concept}
  \begin{columns}[t]
    \column{0.6\textwidth}
    \begin{itemize}
    \item<1-> Integer values represented as 32-bit integers called cells
    \item<2-> Encoding a 64-bit value requires two cells
    \item<3-> \code{#address-cells} and \code{#size-cells}: how many cells
      are used in sub-nodes to encode the address and size in the
      \code{reg} property
    \item<4-> \code{#interrupts-cells}: how many cells are used to encode
      interrupt specifiers for this interrupt controller
    \item<5-> Ditto \code{#clock-cells}, \code{#gpio-cells},
      \code{#phy-cells}, \code{#pwm-cells}, \code{#dma-cells}, etc.
    \end{itemize}
    \column{0.4\textwidth}
    \begin{onlyenv}<1>
      \begin{block}{}
        {\tiny
\begin{minted}{perl}
soc {
   /* This property has 1 cell */
   foo = <0xdeadbeef>;
};
\end{minted}
        }
      \end{block}
    \end{onlyenv}
    \begin{onlyenv}<2>
      \begin{block}{}
        {\tiny
\begin{minted}{perl}
soc {
   /* This property has 2 cells */
   foo = <0xdeadbeef 0xbadcafe>;
};
\end{minted}
        }
      \end{block}
    \end{onlyenv}
    \begin{onlyenv}<3>
      \begin{block}{}
        {\tiny
\begin{minted}{perl}
soc {
   compatible = "simple-bus";
   #address-cells = <1>;
   #size-cells = <1>;

   i2c@f1001000 {
      reg = <0xf1001000 0x1000>;
      #address-cells = <1>;
      #size-cells = <0>;

      eeprom@52 {
         reg = <0x52>;
      };
   };
};
\end{minted}
        }
      \end{block}
    \end{onlyenv}
    \begin{onlyenv}<4>
      \begin{block}{}
        {\tiny
\begin{minted}{perl}
soc {
   intc: interrupt-controller@f1002000 {
       compatible = "foo,bar-intc";
       reg = <0xf1002000 0x1000>;
       interrupt-controller;
       #interrupt-cells = <2>;
   };

   i2c@f1001000 {
       interrupt-parent = <&intc>;
       /* Must have two cells */
       interrupts = <12 24>;
   };
};
\end{minted}
        }
      \end{block}
    \end{onlyenv}
    \begin{onlyenv}<5>
      \begin{block}{}
        {\tiny
\begin{minted}{perl}
soc {
   clkc: clock@f1003000 {
       compatible = "foo,bar-clock";
       reg = <0xf1003000 0x1000>;
       #clock-cells = <3>;
   };

   i2c@f1001000 {
       /* Must have three cells */
       clocks = <&clkc 12 24 32>;
   };
};
\end{minted}
        }
      \end{block}
    \end{onlyenv}
  \end{columns}
\end{frame}

\begin{frame}[fragile]{{\tt -names} properties}
  \begin{itemize}
  \item Some properties are associated to a corresponding
    \code{<prop>-names} property
  \item Gives some human-readable names to entries of the
    corresponding \code{<prop>} properties
    \begin{block}{}
\begin{minted}{perl}
interrupts      = <0 59 0>, <0 70 0>;
interrupt-names = "macirq", "macpmt";
clocks          = <&car 39>, <&car 45>, <&car 86>, <&car 87>;
clock-names     = "gnssm_rgmii", "gnssm_gmac", "rgmii", "gmac";
\end{minted}
    \end{block}
  \item Such names can be typically be used by the driver
    \begin{itemize}
    \item \code{platform_get_irq_byname(pdev, "macirq");}
    \end{itemize}
  \end{itemize}
\end{frame}

\begin{frame}{Conclusion}
  \begin{itemize}
  \item Representation of non-discoverable hardware
  \item Tree of nodes, with properties
  \item Standardization based on {\em Device Tree bindings}
  \item New description language with lots of properties and sometimes
    complex bindings
  \item Used for numerous CPU architectures
  \item Now widely used outside of Linux
  \item A must know for all embedded Linux developers!
  \end{itemize}
\end{frame}

\questionslide

\end{document}
