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 */ | |
22 | / { | |
23 | compatible = "corp,foo"; | |
24 | ||
25 | /* shared resources */ | |
26 | res: res { | |
27 | }; | |
28 | ||
29 | /* On chip peripherals */ | |
30 | ocp: ocp { | |
31 | /* peripherals that are always instantiated */ | |
32 | peripheral1 { ... }; | |
33 | } | |
34 | }; | |
35 | ---- foo.dts ----------------------------------------------------------------- | |
36 | ||
ce013f13 | 37 | The overlay bar.dts, when loaded (and resolved as described in [1]) should |
7518b589 PA |
38 | |
39 | ---- bar.dts ----------------------------------------------------------------- | |
40 | /plugin/; /* allow undefined label references and record them */ | |
41 | / { | |
42 | .... /* various properties for loader use; i.e. part id etc. */ | |
43 | fragment@0 { | |
44 | target = <&ocp>; | |
45 | __overlay__ { | |
46 | /* bar peripheral */ | |
47 | bar { | |
48 | compatible = "corp,bar"; | |
49 | ... /* various properties and child nodes */ | |
50 | } | |
51 | }; | |
52 | }; | |
53 | }; | |
54 | ---- bar.dts ----------------------------------------------------------------- | |
55 | ||
56 | result in foo+bar.dts | |
57 | ||
58 | ---- foo+bar.dts ------------------------------------------------------------- | |
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 */ | |
76 | } | |
77 | } | |
78 | }; | |
79 | ---- foo+bar.dts ------------------------------------------------------------- | |
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 | ||
85 | Overlay in-kernel API | |
86 | -------------------------------- | |
87 | ||
88 | The API is quite easy to use. | |
89 | ||
93a60390 FR |
90 | 1. Call of_overlay_fdt_apply() to create and apply an overlay changeset. The |
91 | return value is an error or a cookie identifying this overlay. | |
7518b589 | 92 | |
0290c4ca | 93 | 2. Call of_overlay_remove() to remove and cleanup the overlay changeset |
d0843e61 GU |
94 | previously created via the call to of_overlay_fdt_apply(). Removal of an |
95 | overlay changeset that is stacked by another will not be permitted. | |
7518b589 PA |
96 | |
97 | Finally, if you need to remove all overlays in one-go, just call | |
0290c4ca | 98 | of_overlay_remove_all() which will remove every single one in the correct |
7518b589 PA |
99 | order. |
100 | ||
83ef4777 JK |
101 | In addition, there is the option to register notifiers that get called on |
102 | overlay operations. See of_overlay_notifier_register/unregister and | |
103 | enum of_overlay_notify_action for details. | |
104 | ||
105 | Note that a notifier callback is not supposed to store pointers to a device | |
106 | tree node or its content beyond OF_OVERLAY_POST_REMOVE corresponding to the | |
107 | respective node it received. | |
108 | ||
7518b589 PA |
109 | Overlay DTS Format |
110 | ------------------ | |
111 | ||
112 | The DTS of an overlay should have the following format: | |
113 | ||
114 | { | |
115 | /* ignored properties by the overlay */ | |
116 | ||
117 | fragment@0 { /* first child node */ | |
118 | ||
119 | target=<phandle>; /* phandle target of the overlay */ | |
120 | or | |
121 | target-path="/path"; /* target path of the overlay */ | |
122 | ||
123 | __overlay__ { | |
124 | property-a; /* add property-a to the target */ | |
125 | node-a { /* add to an existing, or create a node-a */ | |
126 | ... | |
127 | }; | |
128 | }; | |
129 | } | |
130 | fragment@1 { /* second child node */ | |
131 | ... | |
132 | }; | |
133 | /* more fragments follow */ | |
134 | } | |
135 | ||
136 | Using the non-phandle based target method allows one to use a base DT which does | |
137 | not contain a __symbols__ node, i.e. it was not compiled with the -@ option. | |
138 | The __symbols__ node is only required for the target=<phandle> method, since it | |
139 | contains the information required to map from a phandle to a tree location. |