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