| Device Tree Overlay Notes |
| ------------------------- |
| |
| This document describes the implementation of the in-kernel |
| device tree overlay functionality residing in drivers/of/overlay.c and is a |
| companion document to Documentation/devicetree/dynamic-resolution-notes.txt[1] |
| |
| How overlays work |
| ----------------- |
| |
| A Device Tree's overlay purpose is to modify the kernel's live tree, and |
| have the modification affecting the state of the kernel in a way that |
| is reflecting the changes. |
| Since the kernel mainly deals with devices, any new device node that result |
| in an active device should have it created while if the device node is either |
| disabled or removed all together, the affected device should be deregistered. |
| |
| Lets take an example where we have a foo board with the following base tree: |
| |
| ---- foo.dts ----------------------------------------------------------------- |
| /* FOO platform */ |
| / { |
| compatible = "corp,foo"; |
| |
| /* shared resources */ |
| res: res { |
| }; |
| |
| /* On chip peripherals */ |
| ocp: ocp { |
| /* peripherals that are always instantiated */ |
| peripheral1 { ... }; |
| } |
| }; |
| ---- foo.dts ----------------------------------------------------------------- |
| |
| The overlay bar.dts, when loaded (and resolved as described in [1]) should |
| |
| ---- bar.dts ----------------------------------------------------------------- |
| /plugin/; /* allow undefined label references and record them */ |
| / { |
| .... /* various properties for loader use; i.e. part id etc. */ |
| fragment@0 { |
| target = <&ocp>; |
| __overlay__ { |
| /* bar peripheral */ |
| bar { |
| compatible = "corp,bar"; |
| ... /* various properties and child nodes */ |
| } |
| }; |
| }; |
| }; |
| ---- bar.dts ----------------------------------------------------------------- |
| |
| result in foo+bar.dts |
| |
| ---- foo+bar.dts ------------------------------------------------------------- |
| /* FOO platform + bar peripheral */ |
| / { |
| compatible = "corp,foo"; |
| |
| /* shared resources */ |
| res: res { |
| }; |
| |
| /* On chip peripherals */ |
| ocp: ocp { |
| /* peripherals that are always instantiated */ |
| peripheral1 { ... }; |
| |
| /* bar peripheral */ |
| bar { |
| compatible = "corp,bar"; |
| ... /* various properties and child nodes */ |
| } |
| } |
| }; |
| ---- foo+bar.dts ------------------------------------------------------------- |
| |
| As a result of the overlay, a new device node (bar) has been created |
| so a bar platform device will be registered and if a matching device driver |
| is loaded the device will be created as expected. |
| |
| Overlay in-kernel API |
| -------------------------------- |
| |
| The API is quite easy to use. |
| |
| 1. Call of_overlay_fdt_apply() to create and apply an overlay changeset. The |
| return value is an error or a cookie identifying this overlay. |
| |
| 2. Call of_overlay_remove() to remove and cleanup the overlay changeset |
| previously created via the call to of_overlay_fdt_apply(). Removal of an |
| overlay changeset that is stacked by another will not be permitted. |
| |
| Finally, if you need to remove all overlays in one-go, just call |
| of_overlay_remove_all() which will remove every single one in the correct |
| order. |
| |
| Overlay DTS Format |
| ------------------ |
| |
| The DTS of an overlay should have the following format: |
| |
| { |
| /* ignored properties by the overlay */ |
| |
| fragment@0 { /* first child node */ |
| |
| target=<phandle>; /* phandle target of the overlay */ |
| or |
| target-path="/path"; /* target path of the overlay */ |
| |
| __overlay__ { |
| property-a; /* add property-a to the target */ |
| node-a { /* add to an existing, or create a node-a */ |
| ... |
| }; |
| }; |
| } |
| fragment@1 { /* second child node */ |
| ... |
| }; |
| /* more fragments follow */ |
| } |
| |
| Using the non-phandle based target method allows one to use a base DT which does |
| not contain a __symbols__ node, i.e. it was not compiled with the -@ option. |
| The __symbols__ node is only required for the target=<phandle> method, since it |
| contains the information required to map from a phandle to a tree location. |