18c2ecf20Sopenharmony_ci.. SPDX-License-Identifier: GPL-2.0
28c2ecf20Sopenharmony_ci
38c2ecf20Sopenharmony_ci=========================
48c2ecf20Sopenharmony_ciDevice Tree Overlay Notes
58c2ecf20Sopenharmony_ci=========================
68c2ecf20Sopenharmony_ci
78c2ecf20Sopenharmony_ciThis document describes the implementation of the in-kernel
88c2ecf20Sopenharmony_cidevice tree overlay functionality residing in drivers/of/overlay.c and is a
98c2ecf20Sopenharmony_cicompanion document to Documentation/devicetree/dynamic-resolution-notes.rst[1]
108c2ecf20Sopenharmony_ci
118c2ecf20Sopenharmony_ciHow overlays work
128c2ecf20Sopenharmony_ci-----------------
138c2ecf20Sopenharmony_ci
148c2ecf20Sopenharmony_ciA Device Tree's overlay purpose is to modify the kernel's live tree, and
158c2ecf20Sopenharmony_cihave the modification affecting the state of the kernel in a way that
168c2ecf20Sopenharmony_ciis reflecting the changes.
178c2ecf20Sopenharmony_ciSince the kernel mainly deals with devices, any new device node that result
188c2ecf20Sopenharmony_ciin an active device should have it created while if the device node is either
198c2ecf20Sopenharmony_cidisabled or removed all together, the affected device should be deregistered.
208c2ecf20Sopenharmony_ci
218c2ecf20Sopenharmony_ciLets take an example where we have a foo board with the following base tree::
228c2ecf20Sopenharmony_ci
238c2ecf20Sopenharmony_ci    ---- foo.dts ---------------------------------------------------------------
248c2ecf20Sopenharmony_ci	/* FOO platform */
258c2ecf20Sopenharmony_ci	/dts-v1/;
268c2ecf20Sopenharmony_ci	/ {
278c2ecf20Sopenharmony_ci		compatible = "corp,foo";
288c2ecf20Sopenharmony_ci
298c2ecf20Sopenharmony_ci		/* shared resources */
308c2ecf20Sopenharmony_ci		res: res {
318c2ecf20Sopenharmony_ci		};
328c2ecf20Sopenharmony_ci
338c2ecf20Sopenharmony_ci		/* On chip peripherals */
348c2ecf20Sopenharmony_ci		ocp: ocp {
358c2ecf20Sopenharmony_ci			/* peripherals that are always instantiated */
368c2ecf20Sopenharmony_ci			peripheral1 { ... };
378c2ecf20Sopenharmony_ci		};
388c2ecf20Sopenharmony_ci	};
398c2ecf20Sopenharmony_ci    ---- foo.dts ---------------------------------------------------------------
408c2ecf20Sopenharmony_ci
418c2ecf20Sopenharmony_ciThe overlay bar.dts,
428c2ecf20Sopenharmony_ci::
438c2ecf20Sopenharmony_ci
448c2ecf20Sopenharmony_ci    ---- bar.dts - overlay target location by label ----------------------------
458c2ecf20Sopenharmony_ci	/dts-v1/;
468c2ecf20Sopenharmony_ci	/plugin/;
478c2ecf20Sopenharmony_ci	&ocp {
488c2ecf20Sopenharmony_ci		/* bar peripheral */
498c2ecf20Sopenharmony_ci		bar {
508c2ecf20Sopenharmony_ci			compatible = "corp,bar";
518c2ecf20Sopenharmony_ci			... /* various properties and child nodes */
528c2ecf20Sopenharmony_ci		};
538c2ecf20Sopenharmony_ci	};
548c2ecf20Sopenharmony_ci    ---- bar.dts ---------------------------------------------------------------
558c2ecf20Sopenharmony_ci
568c2ecf20Sopenharmony_ciwhen loaded (and resolved as described in [1]) should result in foo+bar.dts::
578c2ecf20Sopenharmony_ci
588c2ecf20Sopenharmony_ci    ---- foo+bar.dts -----------------------------------------------------------
598c2ecf20Sopenharmony_ci	/* FOO platform + bar peripheral */
608c2ecf20Sopenharmony_ci	/ {
618c2ecf20Sopenharmony_ci		compatible = "corp,foo";
628c2ecf20Sopenharmony_ci
638c2ecf20Sopenharmony_ci		/* shared resources */
648c2ecf20Sopenharmony_ci		res: res {
658c2ecf20Sopenharmony_ci		};
668c2ecf20Sopenharmony_ci
678c2ecf20Sopenharmony_ci		/* On chip peripherals */
688c2ecf20Sopenharmony_ci		ocp: ocp {
698c2ecf20Sopenharmony_ci			/* peripherals that are always instantiated */
708c2ecf20Sopenharmony_ci			peripheral1 { ... };
718c2ecf20Sopenharmony_ci
728c2ecf20Sopenharmony_ci			/* bar peripheral */
738c2ecf20Sopenharmony_ci			bar {
748c2ecf20Sopenharmony_ci				compatible = "corp,bar";
758c2ecf20Sopenharmony_ci				... /* various properties and child nodes */
768c2ecf20Sopenharmony_ci			};
778c2ecf20Sopenharmony_ci		};
788c2ecf20Sopenharmony_ci	};
798c2ecf20Sopenharmony_ci    ---- foo+bar.dts -----------------------------------------------------------
808c2ecf20Sopenharmony_ci
818c2ecf20Sopenharmony_ciAs a result of the overlay, a new device node (bar) has been created
828c2ecf20Sopenharmony_ciso a bar platform device will be registered and if a matching device driver
838c2ecf20Sopenharmony_ciis loaded the device will be created as expected.
848c2ecf20Sopenharmony_ci
858c2ecf20Sopenharmony_ciIf the base DT was not compiled with the -@ option then the "&ocp" label
868c2ecf20Sopenharmony_ciwill not be available to resolve the overlay node(s) to the proper location
878c2ecf20Sopenharmony_ciin the base DT. In this case, the target path can be provided. The target
888c2ecf20Sopenharmony_cilocation by label syntax is preferred because the overlay can be applied to
898c2ecf20Sopenharmony_ciany base DT containing the label, no matter where the label occurs in the DT.
908c2ecf20Sopenharmony_ci
918c2ecf20Sopenharmony_ciThe above bar.dts example modified to use target path syntax is::
928c2ecf20Sopenharmony_ci
938c2ecf20Sopenharmony_ci    ---- bar.dts - overlay target location by explicit path --------------------
948c2ecf20Sopenharmony_ci	/dts-v1/;
958c2ecf20Sopenharmony_ci	/plugin/;
968c2ecf20Sopenharmony_ci	&{/ocp} {
978c2ecf20Sopenharmony_ci		/* bar peripheral */
988c2ecf20Sopenharmony_ci		bar {
998c2ecf20Sopenharmony_ci			compatible = "corp,bar";
1008c2ecf20Sopenharmony_ci			... /* various properties and child nodes */
1018c2ecf20Sopenharmony_ci		}
1028c2ecf20Sopenharmony_ci	};
1038c2ecf20Sopenharmony_ci    ---- bar.dts ---------------------------------------------------------------
1048c2ecf20Sopenharmony_ci
1058c2ecf20Sopenharmony_ci
1068c2ecf20Sopenharmony_ciOverlay in-kernel API
1078c2ecf20Sopenharmony_ci--------------------------------
1088c2ecf20Sopenharmony_ci
1098c2ecf20Sopenharmony_ciThe API is quite easy to use.
1108c2ecf20Sopenharmony_ci
1118c2ecf20Sopenharmony_ci1) Call of_overlay_fdt_apply() to create and apply an overlay changeset. The
1128c2ecf20Sopenharmony_ci   return value is an error or a cookie identifying this overlay.
1138c2ecf20Sopenharmony_ci
1148c2ecf20Sopenharmony_ci2) Call of_overlay_remove() to remove and cleanup the overlay changeset
1158c2ecf20Sopenharmony_ci   previously created via the call to of_overlay_fdt_apply(). Removal of an
1168c2ecf20Sopenharmony_ci   overlay changeset that is stacked by another will not be permitted.
1178c2ecf20Sopenharmony_ci
1188c2ecf20Sopenharmony_ciFinally, if you need to remove all overlays in one-go, just call
1198c2ecf20Sopenharmony_ciof_overlay_remove_all() which will remove every single one in the correct
1208c2ecf20Sopenharmony_ciorder.
1218c2ecf20Sopenharmony_ci
1228c2ecf20Sopenharmony_ciIn addition, there is the option to register notifiers that get called on
1238c2ecf20Sopenharmony_cioverlay operations. See of_overlay_notifier_register/unregister and
1248c2ecf20Sopenharmony_cienum of_overlay_notify_action for details.
1258c2ecf20Sopenharmony_ci
1268c2ecf20Sopenharmony_ciNote that a notifier callback is not supposed to store pointers to a device
1278c2ecf20Sopenharmony_citree node or its content beyond OF_OVERLAY_POST_REMOVE corresponding to the
1288c2ecf20Sopenharmony_cirespective node it received.
129