xref: /linux/Documentation/devicetree/overlay-notes.rst (revision 4f2c0a4acffbec01079c28f839422e64ddeff004)
1642e6e5cSMauro Carvalho Chehab.. SPDX-License-Identifier: GPL-2.0
2642e6e5cSMauro Carvalho Chehab
37248213cSRob Herring========================
47248213cSRob HerringDevicetree Overlay Notes
57248213cSRob Herring========================
6642e6e5cSMauro Carvalho Chehab
7642e6e5cSMauro Carvalho ChehabThis document describes the implementation of the in-kernel
8642e6e5cSMauro Carvalho Chehabdevice tree overlay functionality residing in drivers/of/overlay.c and is a
9642e6e5cSMauro Carvalho Chehabcompanion document to Documentation/devicetree/dynamic-resolution-notes.rst[1]
10642e6e5cSMauro Carvalho Chehab
11642e6e5cSMauro Carvalho ChehabHow overlays work
12642e6e5cSMauro Carvalho Chehab-----------------
13642e6e5cSMauro Carvalho Chehab
147248213cSRob HerringA Devicetree's overlay purpose is to modify the kernel's live tree, and
15642e6e5cSMauro Carvalho Chehabhave the modification affecting the state of the kernel in a way that
16642e6e5cSMauro Carvalho Chehabis reflecting the changes.
17642e6e5cSMauro Carvalho ChehabSince the kernel mainly deals with devices, any new device node that result
18642e6e5cSMauro Carvalho Chehabin an active device should have it created while if the device node is either
19642e6e5cSMauro Carvalho Chehabdisabled or removed all together, the affected device should be deregistered.
20642e6e5cSMauro Carvalho Chehab
21642e6e5cSMauro Carvalho ChehabLets take an example where we have a foo board with the following base tree::
22642e6e5cSMauro Carvalho Chehab
23642e6e5cSMauro Carvalho Chehab    ---- foo.dts ---------------------------------------------------------------
24642e6e5cSMauro Carvalho Chehab	/* FOO platform */
25642e6e5cSMauro Carvalho Chehab	/dts-v1/;
26642e6e5cSMauro Carvalho Chehab	/ {
27642e6e5cSMauro Carvalho Chehab		compatible = "corp,foo";
28642e6e5cSMauro Carvalho Chehab
29642e6e5cSMauro Carvalho Chehab		/* shared resources */
30642e6e5cSMauro Carvalho Chehab		res: res {
31642e6e5cSMauro Carvalho Chehab		};
32642e6e5cSMauro Carvalho Chehab
33642e6e5cSMauro Carvalho Chehab		/* On chip peripherals */
34642e6e5cSMauro Carvalho Chehab		ocp: ocp {
35642e6e5cSMauro Carvalho Chehab			/* peripherals that are always instantiated */
36642e6e5cSMauro Carvalho Chehab			peripheral1 { ... };
37642e6e5cSMauro Carvalho Chehab		};
38642e6e5cSMauro Carvalho Chehab	};
39642e6e5cSMauro Carvalho Chehab    ---- foo.dts ---------------------------------------------------------------
40642e6e5cSMauro Carvalho Chehab
41642e6e5cSMauro Carvalho ChehabThe overlay bar.dts,
42642e6e5cSMauro Carvalho Chehab::
43642e6e5cSMauro Carvalho Chehab
44642e6e5cSMauro Carvalho Chehab    ---- bar.dts - overlay target location by label ----------------------------
45642e6e5cSMauro Carvalho Chehab	/dts-v1/;
46642e6e5cSMauro Carvalho Chehab	/plugin/;
47642e6e5cSMauro Carvalho Chehab	&ocp {
48642e6e5cSMauro Carvalho Chehab		/* bar peripheral */
49642e6e5cSMauro Carvalho Chehab		bar {
50642e6e5cSMauro Carvalho Chehab			compatible = "corp,bar";
51642e6e5cSMauro Carvalho Chehab			... /* various properties and child nodes */
52642e6e5cSMauro Carvalho Chehab		};
53642e6e5cSMauro Carvalho Chehab	};
54642e6e5cSMauro Carvalho Chehab    ---- bar.dts ---------------------------------------------------------------
55642e6e5cSMauro Carvalho Chehab
56642e6e5cSMauro Carvalho Chehabwhen loaded (and resolved as described in [1]) should result in foo+bar.dts::
57642e6e5cSMauro Carvalho Chehab
58642e6e5cSMauro Carvalho Chehab    ---- foo+bar.dts -----------------------------------------------------------
59642e6e5cSMauro Carvalho Chehab	/* FOO platform + bar peripheral */
60642e6e5cSMauro Carvalho Chehab	/ {
61642e6e5cSMauro Carvalho Chehab		compatible = "corp,foo";
62642e6e5cSMauro Carvalho Chehab
63642e6e5cSMauro Carvalho Chehab		/* shared resources */
64642e6e5cSMauro Carvalho Chehab		res: res {
65642e6e5cSMauro Carvalho Chehab		};
66642e6e5cSMauro Carvalho Chehab
67642e6e5cSMauro Carvalho Chehab		/* On chip peripherals */
68642e6e5cSMauro Carvalho Chehab		ocp: ocp {
69642e6e5cSMauro Carvalho Chehab			/* peripherals that are always instantiated */
70642e6e5cSMauro Carvalho Chehab			peripheral1 { ... };
71642e6e5cSMauro Carvalho Chehab
72642e6e5cSMauro Carvalho Chehab			/* bar peripheral */
73642e6e5cSMauro Carvalho Chehab			bar {
74642e6e5cSMauro Carvalho Chehab				compatible = "corp,bar";
75642e6e5cSMauro Carvalho Chehab				... /* various properties and child nodes */
76642e6e5cSMauro Carvalho Chehab			};
77642e6e5cSMauro Carvalho Chehab		};
78642e6e5cSMauro Carvalho Chehab	};
79642e6e5cSMauro Carvalho Chehab    ---- foo+bar.dts -----------------------------------------------------------
80642e6e5cSMauro Carvalho Chehab
81642e6e5cSMauro Carvalho ChehabAs a result of the overlay, a new device node (bar) has been created
82642e6e5cSMauro Carvalho Chehabso a bar platform device will be registered and if a matching device driver
83642e6e5cSMauro Carvalho Chehabis loaded the device will be created as expected.
84642e6e5cSMauro Carvalho Chehab
85642e6e5cSMauro Carvalho ChehabIf the base DT was not compiled with the -@ option then the "&ocp" label
86642e6e5cSMauro Carvalho Chehabwill not be available to resolve the overlay node(s) to the proper location
87642e6e5cSMauro Carvalho Chehabin the base DT. In this case, the target path can be provided. The target
88642e6e5cSMauro Carvalho Chehablocation by label syntax is preferred because the overlay can be applied to
89642e6e5cSMauro Carvalho Chehabany base DT containing the label, no matter where the label occurs in the DT.
90642e6e5cSMauro Carvalho Chehab
91642e6e5cSMauro Carvalho ChehabThe above bar.dts example modified to use target path syntax is::
92642e6e5cSMauro Carvalho Chehab
93642e6e5cSMauro Carvalho Chehab    ---- bar.dts - overlay target location by explicit path --------------------
94642e6e5cSMauro Carvalho Chehab	/dts-v1/;
95642e6e5cSMauro Carvalho Chehab	/plugin/;
96642e6e5cSMauro Carvalho Chehab	&{/ocp} {
97642e6e5cSMauro Carvalho Chehab		/* bar peripheral */
98642e6e5cSMauro Carvalho Chehab		bar {
99642e6e5cSMauro Carvalho Chehab			compatible = "corp,bar";
100642e6e5cSMauro Carvalho Chehab			... /* various properties and child nodes */
101642e6e5cSMauro Carvalho Chehab		}
102642e6e5cSMauro Carvalho Chehab	};
103642e6e5cSMauro Carvalho Chehab    ---- bar.dts ---------------------------------------------------------------
104642e6e5cSMauro Carvalho Chehab
105642e6e5cSMauro Carvalho Chehab
106642e6e5cSMauro Carvalho ChehabOverlay in-kernel API
107642e6e5cSMauro Carvalho Chehab--------------------------------
108642e6e5cSMauro Carvalho Chehab
109642e6e5cSMauro Carvalho ChehabThe API is quite easy to use.
110642e6e5cSMauro Carvalho Chehab
111642e6e5cSMauro Carvalho Chehab1) Call of_overlay_fdt_apply() to create and apply an overlay changeset. The
112642e6e5cSMauro Carvalho Chehab   return value is an error or a cookie identifying this overlay.
113642e6e5cSMauro Carvalho Chehab
114642e6e5cSMauro Carvalho Chehab2) Call of_overlay_remove() to remove and cleanup the overlay changeset
115642e6e5cSMauro Carvalho Chehab   previously created via the call to of_overlay_fdt_apply(). Removal of an
116642e6e5cSMauro Carvalho Chehab   overlay changeset that is stacked by another will not be permitted.
117642e6e5cSMauro Carvalho Chehab
118642e6e5cSMauro Carvalho ChehabFinally, if you need to remove all overlays in one-go, just call
119642e6e5cSMauro Carvalho Chehabof_overlay_remove_all() which will remove every single one in the correct
120642e6e5cSMauro Carvalho Chehaborder.
121642e6e5cSMauro Carvalho Chehab
122*067c0987SFrank RowandThere is the option to register notifiers that get called on
123642e6e5cSMauro Carvalho Chehaboverlay operations. See of_overlay_notifier_register/unregister and
124642e6e5cSMauro Carvalho Chehabenum of_overlay_notify_action for details.
125642e6e5cSMauro Carvalho Chehab
126*067c0987SFrank RowandA notifier callback for OF_OVERLAY_PRE_APPLY, OF_OVERLAY_POST_APPLY, or
127*067c0987SFrank RowandOF_OVERLAY_PRE_REMOVE may store pointers to a device tree node in the overlay
128*067c0987SFrank Rowandor its content but these pointers must not persist past the notifier callback
129*067c0987SFrank Rowandfor OF_OVERLAY_POST_REMOVE.  The memory containing the overlay will be
130*067c0987SFrank Rowandkfree()ed after OF_OVERLAY_POST_REMOVE notifiers are called.  Note that the
131*067c0987SFrank Rowandmemory will be kfree()ed even if the notifier for OF_OVERLAY_POST_REMOVE
132*067c0987SFrank Rowandreturns an error.
133*067c0987SFrank Rowand
134*067c0987SFrank RowandThe changeset notifiers in drivers/of/dynamic.c are a second type of notifier
135*067c0987SFrank Rowandthat could be triggered by applying or removing an overlay.  These notifiers
136*067c0987SFrank Rowandare not allowed to store pointers to a device tree node in the overlay
137*067c0987SFrank Rowandor its content.  The overlay code does not protect against such pointers
138*067c0987SFrank Rowandremaining active when the memory containing the overlay is freed as a result
139*067c0987SFrank Rowandof removing the overlay.
140*067c0987SFrank Rowand
141*067c0987SFrank RowandAny other code that retains a pointer to the overlay nodes or data is
142*067c0987SFrank Rowandconsidered to be a bug because after removing the overlay the pointer
143*067c0987SFrank Rowandwill refer to freed memory.
144*067c0987SFrank Rowand
145*067c0987SFrank RowandUsers of overlays must be especially aware of the overall operations that
146*067c0987SFrank Rowandoccur on the system to ensure that other kernel code does not retain any
147*067c0987SFrank Rowandpointers to the overlay nodes or data.  Any example of an inadvertent use
148*067c0987SFrank Rowandof such pointers is if a driver or subsystem module is loaded after an
149*067c0987SFrank Rowandoverlay has been applied, and the driver or subsystem scans the entire
150*067c0987SFrank Rowanddevicetree or a large portion of it, including the overlay nodes.
151