^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) .. SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) =========================
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) Device Tree Overlay Notes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) =========================
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) This document describes the implementation of the in-kernel
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) device tree overlay functionality residing in drivers/of/overlay.c and is a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) companion document to Documentation/devicetree/dynamic-resolution-notes.rst[1]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) How overlays work
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) -----------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) A Device Tree's overlay purpose is to modify the kernel's live tree, and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) have the modification affecting the state of the kernel in a way that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) is reflecting the changes.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) Since the kernel mainly deals with devices, any new device node that result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) in an active device should have it created while if the device node is either
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) disabled or removed all together, the affected device should be deregistered.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) Lets take an example where we have a foo board with the following base tree::
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) ---- foo.dts ---------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) /* FOO platform */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) /dts-v1/;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) / {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) compatible = "corp,foo";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) /* shared resources */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) res: res {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) /* On chip peripherals */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) ocp: ocp {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) /* peripherals that are always instantiated */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) peripheral1 { ... };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) ---- foo.dts ---------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) The overlay bar.dts,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) ::
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) ---- bar.dts - overlay target location by label ----------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) /dts-v1/;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) /plugin/;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) &ocp {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) /* bar peripheral */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) bar {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) compatible = "corp,bar";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) ... /* various properties and child nodes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) ---- bar.dts ---------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) when loaded (and resolved as described in [1]) should result in foo+bar.dts::
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) ---- foo+bar.dts -----------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) /* FOO platform + bar peripheral */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) / {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) compatible = "corp,foo";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) /* shared resources */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) res: res {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) /* On chip peripherals */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) ocp: ocp {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) /* peripherals that are always instantiated */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) peripheral1 { ... };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) /* bar peripheral */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) bar {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) compatible = "corp,bar";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) ... /* various properties and child nodes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) ---- foo+bar.dts -----------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) As a result of the overlay, a new device node (bar) has been created
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) so a bar platform device will be registered and if a matching device driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) is loaded the device will be created as expected.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) If the base DT was not compiled with the -@ option then the "&ocp" label
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) will not be available to resolve the overlay node(s) to the proper location
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) in the base DT. In this case, the target path can be provided. The target
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) location by label syntax is preferred because the overlay can be applied to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) any base DT containing the label, no matter where the label occurs in the DT.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) The above bar.dts example modified to use target path syntax is::
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) ---- bar.dts - overlay target location by explicit path --------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) /dts-v1/;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) /plugin/;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) &{/ocp} {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) /* bar peripheral */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) bar {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) compatible = "corp,bar";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) ... /* various properties and child nodes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) ---- bar.dts ---------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) Overlay in-kernel API
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) --------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) The API is quite easy to use.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 1) Call of_overlay_fdt_apply() to create and apply an overlay changeset. The
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) return value is an error or a cookie identifying this overlay.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 2) Call of_overlay_remove() to remove and cleanup the overlay changeset
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) previously created via the call to of_overlay_fdt_apply(). Removal of an
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) overlay changeset that is stacked by another will not be permitted.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) Finally, if you need to remove all overlays in one-go, just call
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) of_overlay_remove_all() which will remove every single one in the correct
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) order.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) In addition, there is the option to register notifiers that get called on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) overlay operations. See of_overlay_notifier_register/unregister and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) enum of_overlay_notify_action for details.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) Note that a notifier callback is not supposed to store pointers to a device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) tree node or its content beyond OF_OVERLAY_POST_REMOVE corresponding to the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) respective node it received.