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 | |
6 | companion document to Documentation/devicetree/dt-object-internal.txt[1] & | |
7 | Documentation/devicetree/dynamic-resolution-notes.txt[2] | |
8 | ||
9 | How overlays work | |
10 | ----------------- | |
11 | ||
12 | A Device Tree's overlay purpose is to modify the kernel's live tree, and | |
ac3e8ea1 | 13 | have the modification affecting the state of the kernel in a way that |
7518b589 PA |
14 | is reflecting the changes. |
15 | Since the kernel mainly deals with devices, any new device node that result | |
16 | in an active device should have it created while if the device node is either | |
17 | disabled or removed all together, the affected device should be deregistered. | |
18 | ||
19 | Lets take an example where we have a foo board with the following base tree | |
20 | which is taken from [1]. | |
21 | ||
22 | ---- foo.dts ----------------------------------------------------------------- | |
23 | /* FOO platform */ | |
24 | / { | |
25 | compatible = "corp,foo"; | |
26 | ||
27 | /* shared resources */ | |
28 | res: res { | |
29 | }; | |
30 | ||
31 | /* On chip peripherals */ | |
32 | ocp: ocp { | |
33 | /* peripherals that are always instantiated */ | |
34 | peripheral1 { ... }; | |
35 | } | |
36 | }; | |
37 | ---- foo.dts ----------------------------------------------------------------- | |
38 | ||
39 | The overlay bar.dts, when loaded (and resolved as described in [2]) should | |
40 | ||
41 | ---- bar.dts ----------------------------------------------------------------- | |
42 | /plugin/; /* allow undefined label references and record them */ | |
43 | / { | |
44 | .... /* various properties for loader use; i.e. part id etc. */ | |
45 | fragment@0 { | |
46 | target = <&ocp>; | |
47 | __overlay__ { | |
48 | /* bar peripheral */ | |
49 | bar { | |
50 | compatible = "corp,bar"; | |
51 | ... /* various properties and child nodes */ | |
52 | } | |
53 | }; | |
54 | }; | |
55 | }; | |
56 | ---- bar.dts ----------------------------------------------------------------- | |
57 | ||
58 | result in foo+bar.dts | |
59 | ||
60 | ---- foo+bar.dts ------------------------------------------------------------- | |
61 | /* FOO platform + bar peripheral */ | |
62 | / { | |
63 | compatible = "corp,foo"; | |
64 | ||
65 | /* shared resources */ | |
66 | res: res { | |
67 | }; | |
68 | ||
69 | /* On chip peripherals */ | |
70 | ocp: ocp { | |
71 | /* peripherals that are always instantiated */ | |
72 | peripheral1 { ... }; | |
73 | ||
74 | /* bar peripheral */ | |
75 | bar { | |
76 | compatible = "corp,bar"; | |
77 | ... /* various properties and child nodes */ | |
78 | } | |
79 | } | |
80 | }; | |
81 | ---- foo+bar.dts ------------------------------------------------------------- | |
82 | ||
ac3e8ea1 | 83 | As a result of the overlay, a new device node (bar) has been created |
7518b589 PA |
84 | so a bar platform device will be registered and if a matching device driver |
85 | is loaded the device will be created as expected. | |
86 | ||
87 | Overlay in-kernel API | |
88 | -------------------------------- | |
89 | ||
90 | The API is quite easy to use. | |
91 | ||
92 | 1. Call of_overlay_create() to create and apply an overlay. The return value | |
93 | is a cookie identifying this overlay. | |
94 | ||
95 | 2. Call of_overlay_destroy() to remove and cleanup the overlay previously | |
96 | created via the call to of_overlay_create(). Removal of an overlay that | |
97 | is stacked by another will not be permitted. | |
98 | ||
99 | Finally, if you need to remove all overlays in one-go, just call | |
100 | of_overlay_destroy_all() which will remove every single one in the correct | |
101 | order. | |
102 | ||
103 | Overlay DTS Format | |
104 | ------------------ | |
105 | ||
106 | The DTS of an overlay should have the following format: | |
107 | ||
108 | { | |
109 | /* ignored properties by the overlay */ | |
110 | ||
111 | fragment@0 { /* first child node */ | |
112 | ||
113 | target=<phandle>; /* phandle target of the overlay */ | |
114 | or | |
115 | target-path="/path"; /* target path of the overlay */ | |
116 | ||
117 | __overlay__ { | |
118 | property-a; /* add property-a to the target */ | |
119 | node-a { /* add to an existing, or create a node-a */ | |
120 | ... | |
121 | }; | |
122 | }; | |
123 | } | |
124 | fragment@1 { /* second child node */ | |
125 | ... | |
126 | }; | |
127 | /* more fragments follow */ | |
128 | } | |
129 | ||
130 | Using the non-phandle based target method allows one to use a base DT which does | |
131 | not contain a __symbols__ node, i.e. it was not compiled with the -@ option. | |
132 | The __symbols__ node is only required for the target=<phandle> method, since it | |
133 | contains the information required to map from a phandle to a tree location. |