]>
Commit | Line | Data |
---|---|---|
642e6e5c MCC |
1 | .. SPDX-License-Identifier: GPL-2.0 |
2 | ||
7248213c RH |
3 | ======================== |
4 | Devicetree Overlay Notes | |
5 | ======================== | |
7518b589 PA |
6 | |
7 | This document describes the implementation of the in-kernel | |
8 | device tree overlay functionality residing in drivers/of/overlay.c and is a | |
26853a24 | 9 | companion document to Documentation/devicetree/dynamic-resolution-notes.rst[1] |
7518b589 PA |
10 | |
11 | How overlays work | |
12 | ----------------- | |
13 | ||
7248213c | 14 | A Devicetree's overlay purpose is to modify the kernel's live tree, and |
ac3e8ea1 | 15 | have the modification affecting the state of the kernel in a way that |
7518b589 PA |
16 | is reflecting the changes. |
17 | Since the kernel mainly deals with devices, any new device node that result | |
18 | in an active device should have it created while if the device node is either | |
19 | disabled or removed all together, the affected device should be deregistered. | |
20 | ||
642e6e5c | 21 | Lets take an example where we have a foo board with the following base tree:: |
7518b589 | 22 | |
642e6e5c | 23 | ---- foo.dts --------------------------------------------------------------- |
7518b589 | 24 | /* FOO platform */ |
9ae8578b | 25 | /dts-v1/; |
7518b589 PA |
26 | / { |
27 | compatible = "corp,foo"; | |
28 | ||
29 | /* shared resources */ | |
30 | res: res { | |
31 | }; | |
32 | ||
33 | /* On chip peripherals */ | |
34 | ocp: ocp { | |
35 | /* peripherals that are always instantiated */ | |
36 | peripheral1 { ... }; | |
9ae8578b | 37 | }; |
7518b589 | 38 | }; |
642e6e5c | 39 | ---- foo.dts --------------------------------------------------------------- |
7518b589 | 40 | |
9ae8578b | 41 | The overlay bar.dts, |
642e6e5c | 42 | :: |
7518b589 | 43 | |
642e6e5c | 44 | ---- bar.dts - overlay target location by label ---------------------------- |
9ae8578b FR |
45 | /dts-v1/; |
46 | /plugin/; | |
47 | &ocp { | |
48 | /* bar peripheral */ | |
49 | bar { | |
50 | compatible = "corp,bar"; | |
51 | ... /* various properties and child nodes */ | |
7518b589 PA |
52 | }; |
53 | }; | |
642e6e5c | 54 | ---- bar.dts --------------------------------------------------------------- |
7518b589 | 55 | |
642e6e5c | 56 | when loaded (and resolved as described in [1]) should result in foo+bar.dts:: |
7518b589 | 57 | |
642e6e5c | 58 | ---- foo+bar.dts ----------------------------------------------------------- |
7518b589 PA |
59 | /* FOO platform + bar peripheral */ |
60 | / { | |
61 | compatible = "corp,foo"; | |
62 | ||
63 | /* shared resources */ | |
64 | res: res { | |
65 | }; | |
66 | ||
67 | /* On chip peripherals */ | |
68 | ocp: ocp { | |
69 | /* peripherals that are always instantiated */ | |
70 | peripheral1 { ... }; | |
71 | ||
72 | /* bar peripheral */ | |
73 | bar { | |
74 | compatible = "corp,bar"; | |
75 | ... /* various properties and child nodes */ | |
9ae8578b FR |
76 | }; |
77 | }; | |
7518b589 | 78 | }; |
642e6e5c | 79 | ---- foo+bar.dts ----------------------------------------------------------- |
7518b589 | 80 | |
ac3e8ea1 | 81 | As a result of the overlay, a new device node (bar) has been created |
7518b589 PA |
82 | so a bar platform device will be registered and if a matching device driver |
83 | is loaded the device will be created as expected. | |
84 | ||
9ae8578b FR |
85 | If the base DT was not compiled with the -@ option then the "&ocp" label |
86 | will not be available to resolve the overlay node(s) to the proper location | |
87 | in the base DT. In this case, the target path can be provided. The target | |
88 | location by label syntax is preferred because the overlay can be applied to | |
89 | any base DT containing the label, no matter where the label occurs in the DT. | |
90 | ||
642e6e5c | 91 | The above bar.dts example modified to use target path syntax is:: |
9ae8578b | 92 | |
642e6e5c | 93 | ---- bar.dts - overlay target location by explicit path -------------------- |
9ae8578b FR |
94 | /dts-v1/; |
95 | /plugin/; | |
96 | &{/ocp} { | |
97 | /* bar peripheral */ | |
98 | bar { | |
99 | compatible = "corp,bar"; | |
100 | ... /* various properties and child nodes */ | |
101 | } | |
102 | }; | |
642e6e5c | 103 | ---- bar.dts --------------------------------------------------------------- |
9ae8578b FR |
104 | |
105 | ||
7518b589 PA |
106 | Overlay in-kernel API |
107 | -------------------------------- | |
108 | ||
109 | The API is quite easy to use. | |
110 | ||
642e6e5c MCC |
111 | 1) Call of_overlay_fdt_apply() to create and apply an overlay changeset. The |
112 | return value is an error or a cookie identifying this overlay. | |
7518b589 | 113 | |
642e6e5c MCC |
114 | 2) Call of_overlay_remove() to remove and cleanup the overlay changeset |
115 | previously created via the call to of_overlay_fdt_apply(). Removal of an | |
116 | overlay changeset that is stacked by another will not be permitted. | |
7518b589 PA |
117 | |
118 | Finally, if you need to remove all overlays in one-go, just call | |
0290c4ca | 119 | of_overlay_remove_all() which will remove every single one in the correct |
7518b589 PA |
120 | order. |
121 | ||
067c0987 | 122 | There is the option to register notifiers that get called on |
83ef4777 JK |
123 | overlay operations. See of_overlay_notifier_register/unregister and |
124 | enum of_overlay_notify_action for details. | |
125 | ||
067c0987 FR |
126 | A notifier callback for OF_OVERLAY_PRE_APPLY, OF_OVERLAY_POST_APPLY, or |
127 | OF_OVERLAY_PRE_REMOVE may store pointers to a device tree node in the overlay | |
128 | or its content but these pointers must not persist past the notifier callback | |
129 | for OF_OVERLAY_POST_REMOVE. The memory containing the overlay will be | |
130 | kfree()ed after OF_OVERLAY_POST_REMOVE notifiers are called. Note that the | |
131 | memory will be kfree()ed even if the notifier for OF_OVERLAY_POST_REMOVE | |
132 | returns an error. | |
133 | ||
134 | The changeset notifiers in drivers/of/dynamic.c are a second type of notifier | |
135 | that could be triggered by applying or removing an overlay. These notifiers | |
136 | are not allowed to store pointers to a device tree node in the overlay | |
137 | or its content. The overlay code does not protect against such pointers | |
138 | remaining active when the memory containing the overlay is freed as a result | |
139 | of removing the overlay. | |
140 | ||
141 | Any other code that retains a pointer to the overlay nodes or data is | |
142 | considered to be a bug because after removing the overlay the pointer | |
143 | will refer to freed memory. | |
144 | ||
145 | Users of overlays must be especially aware of the overall operations that | |
146 | occur on the system to ensure that other kernel code does not retain any | |
147 | pointers to the overlay nodes or data. Any example of an inadvertent use | |
148 | of such pointers is if a driver or subsystem module is loaded after an | |
149 | overlay has been applied, and the driver or subsystem scans the entire | |
150 | devicetree or a large portion of it, including the overlay nodes. |