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