Change-Id: I78b3c384bd04b2ba6a558913d485bf2eaa9f09e8
Reviewed-on: http://photon-jenkins.eng.vmware.com:8082/7695
Tested-by: gerrit-photon <photon-checkins@vmware.com>
Reviewed-by: Alexey Makhalov <amakhalov@vmware.com>
(cherry picked from commit f89e21628ea04c196d890d6a038ab616a99eaf12)
Reviewed-on: http://photon-jenkins.eng.vmware.com:8082/7712
1 | 1 |
new file mode 100644 |
... | ... |
@@ -0,0 +1,441 @@ |
0 |
+From c997ff2f4ced80be724c52e1105f75ece966765b Mon Sep 17 00:00:00 2001 |
|
1 |
+From: Pantelis Antoniou <pantelis.antoniou@konsulko.com> |
|
2 |
+Date: Wed, 3 Dec 2014 13:23:28 +0200 |
|
3 |
+Subject: [PATCH] OF: DT-Overlay configfs interface |
|
4 |
+ |
|
5 |
+This is a port of Pantelis Antoniou's v3 port that makes use of the |
|
6 |
+new upstreamed configfs support for binary attributes. |
|
7 |
+ |
|
8 |
+Original commit message: |
|
9 |
+ |
|
10 |
+Add a runtime interface to using configfs for generic device tree overlay |
|
11 |
+usage. With it its possible to use device tree overlays without having |
|
12 |
+to use a per-platform overlay manager. |
|
13 |
+ |
|
14 |
+Please see Documentation/devicetree/configfs-overlays.txt for more info. |
|
15 |
+ |
|
16 |
+Changes since v2: |
|
17 |
+- Removed ifdef CONFIG_OF_OVERLAY (since for now it's required) |
|
18 |
+- Created a documentation entry |
|
19 |
+- Slight rewording in Kconfig |
|
20 |
+ |
|
21 |
+Changes since v1: |
|
22 |
+- of_resolve() -> of_resolve_phandles(). |
|
23 |
+ |
|
24 |
+Originally-signed-off-by: Pantelis Antoniou <pantelis.antoniou@konsulko.com> |
|
25 |
+Signed-off-by: Phil Elwell <phil@raspberrypi.org> |
|
26 |
+ |
|
27 |
+DT configfs: Fix build errors on other platforms |
|
28 |
+ |
|
29 |
+Signed-off-by: Phil Elwell <phil@raspberrypi.org> |
|
30 |
+ |
|
31 |
+DT configfs: fix build error |
|
32 |
+ |
|
33 |
+There is an error when compiling rpi-4.6.y branch: |
|
34 |
+ CC drivers/of/configfs.o |
|
35 |
+drivers/of/configfs.c:291:21: error: initialization from incompatible pointer type [-Werror=incompatible-pointer-types] |
|
36 |
+ .default_groups = of_cfs_def_groups, |
|
37 |
+ ^ |
|
38 |
+drivers/of/configfs.c:291:21: note: (near initialization for 'of_cfs_subsys.su_group.default_groups.next') |
|
39 |
+ |
|
40 |
+The .default_groups is linked list since commit |
|
41 |
+1ae1602de028acaa42a0f6ff18d19756f8e825c6. |
|
42 |
+This commit uses configfs_add_default_group to fix this problem. |
|
43 |
+ |
|
44 |
+Signed-off-by: Slawomir Stepien <sst@poczta.fm> |
|
45 |
+Signed-off-by: Ajay Kaher <akaher@vmware.com> |
|
46 |
+ |
|
47 |
+configfs: New of_overlay API |
|
48 |
+--- |
|
49 |
+ Documentation/devicetree/configfs-overlays.txt | 31 +++ |
|
50 |
+ drivers/of/Kconfig | 7 + |
|
51 |
+ drivers/of/Makefile | 1 + |
|
52 |
+ drivers/of/configfs.c | 310 +++++++++++++++++++++++++ |
|
53 |
+ 4 files changed, 349 insertions(+) |
|
54 |
+ create mode 100644 Documentation/devicetree/configfs-overlays.txt |
|
55 |
+ create mode 100644 drivers/of/configfs.c |
|
56 |
+ |
|
57 |
+diff --git a/Documentation/devicetree/configfs-overlays.txt b/Documentation/devicetree/configfs-overlays.txt |
|
58 |
+new file mode 100644 |
|
59 |
+index 0000000..5fa43e0 |
|
60 |
+--- /dev/null |
|
61 |
+@@ -0,0 +1,31 @@ |
|
62 |
++Howto use the configfs overlay interface. |
|
63 |
++ |
|
64 |
++A device-tree configfs entry is created in /config/device-tree/overlays |
|
65 |
++and and it is manipulated using standard file system I/O. |
|
66 |
++Note that this is a debug level interface, for use by developers and |
|
67 |
++not necessarily something accessed by normal users due to the |
|
68 |
++security implications of having direct access to the kernel's device tree. |
|
69 |
++ |
|
70 |
++* To create an overlay you mkdir the directory: |
|
71 |
++ |
|
72 |
++ # mkdir /config/device-tree/overlays/foo |
|
73 |
++ |
|
74 |
++* Either you echo the overlay firmware file to the path property file. |
|
75 |
++ |
|
76 |
++ # echo foo.dtbo >/config/device-tree/overlays/foo/path |
|
77 |
++ |
|
78 |
++* Or you cat the contents of the overlay to the dtbo file |
|
79 |
++ |
|
80 |
++ # cat foo.dtbo >/config/device-tree/overlays/foo/dtbo |
|
81 |
++ |
|
82 |
++The overlay file will be applied, and devices will be created/destroyed |
|
83 |
++as required. |
|
84 |
++ |
|
85 |
++To remove it simply rmdir the directory. |
|
86 |
++ |
|
87 |
++ # rmdir /config/device-tree/overlays/foo |
|
88 |
++ |
|
89 |
++The rationalle of the dual interface (firmware & direct copy) is that each is |
|
90 |
++better suited to different use patterns. The firmware interface is what's |
|
91 |
++intended to be used by hardware managers in the kernel, while the copy interface |
|
92 |
++make sense for developers (since it avoids problems with namespaces). |
|
93 |
+diff --git a/drivers/of/Kconfig b/drivers/of/Kconfig |
|
94 |
+index ad3fcad..3c808e2 100644 |
|
95 |
+--- a/drivers/of/Kconfig |
|
96 |
+@@ -103,4 +103,11 @@ config OF_OVERLAY |
|
97 |
+ config OF_NUMA |
|
98 |
+ bool |
|
99 |
+ |
|
100 |
++config OF_CONFIGFS |
|
101 |
++ bool "Device Tree Overlay ConfigFS interface" |
|
102 |
++ select CONFIGFS_FS |
|
103 |
++ select OF_OVERLAY |
|
104 |
++ help |
|
105 |
++ Enable a simple user-space driven DT overlay interface. |
|
106 |
++ |
|
107 |
+ endif # OF |
|
108 |
+diff --git a/drivers/of/Makefile b/drivers/of/Makefile |
|
109 |
+index 663a4af..b00a95a 100644 |
|
110 |
+--- a/drivers/of/Makefile |
|
111 |
+@@ -1,6 +1,7 @@ |
|
112 |
+ # SPDX-License-Identifier: GPL-2.0 |
|
113 |
+ obj-y = base.o device.o platform.o property.o |
|
114 |
+ obj-$(CONFIG_OF_KOBJ) += kobj.o |
|
115 |
++obj-$(CONFIG_OF_CONFIGFS) += configfs.o |
|
116 |
+ obj-$(CONFIG_OF_DYNAMIC) += dynamic.o |
|
117 |
+ obj-$(CONFIG_OF_FLATTREE) += fdt.o |
|
118 |
+ obj-$(CONFIG_OF_EARLY_FLATTREE) += fdt_address.o |
|
119 |
+diff --git a/drivers/of/configfs.c b/drivers/of/configfs.c |
|
120 |
+new file mode 100644 |
|
121 |
+index 0000000..178f062 |
|
122 |
+--- /dev/null |
|
123 |
+@@ -0,0 +1,310 @@ |
|
124 |
++/* |
|
125 |
++ * Configfs entries for device-tree |
|
126 |
++ * |
|
127 |
++ * Copyright (C) 2013 - Pantelis Antoniou <panto@antoniou-consulting.com> |
|
128 |
++ * |
|
129 |
++ * This program is free software; you can redistribute it and/or |
|
130 |
++ * modify it under the terms of the GNU General Public License |
|
131 |
++ * as published by the Free Software Foundation; either version |
|
132 |
++ * 2 of the License, or (at your option) any later version. |
|
133 |
++ */ |
|
134 |
++#include <linux/ctype.h> |
|
135 |
++#include <linux/cpu.h> |
|
136 |
++#include <linux/module.h> |
|
137 |
++#include <linux/of.h> |
|
138 |
++#include <linux/of_fdt.h> |
|
139 |
++#include <linux/spinlock.h> |
|
140 |
++#include <linux/slab.h> |
|
141 |
++#include <linux/proc_fs.h> |
|
142 |
++#include <linux/configfs.h> |
|
143 |
++#include <linux/types.h> |
|
144 |
++#include <linux/stat.h> |
|
145 |
++#include <linux/limits.h> |
|
146 |
++#include <linux/file.h> |
|
147 |
++#include <linux/vmalloc.h> |
|
148 |
++#include <linux/firmware.h> |
|
149 |
++#include <linux/sizes.h> |
|
150 |
++ |
|
151 |
++#include "of_private.h" |
|
152 |
++ |
|
153 |
++struct cfs_overlay_item { |
|
154 |
++ struct config_item item; |
|
155 |
++ |
|
156 |
++ char path[PATH_MAX]; |
|
157 |
++ |
|
158 |
++ const struct firmware *fw; |
|
159 |
++ struct device_node *overlay; |
|
160 |
++ int ov_id; |
|
161 |
++ |
|
162 |
++ void *dtbo; |
|
163 |
++ int dtbo_size; |
|
164 |
++}; |
|
165 |
++ |
|
166 |
++static int create_overlay(struct cfs_overlay_item *overlay, void *blob) |
|
167 |
++{ |
|
168 |
++ int err; |
|
169 |
++ |
|
170 |
++ /* unflatten the tree */ |
|
171 |
++ of_fdt_unflatten_tree(blob, NULL, &overlay->overlay); |
|
172 |
++ if (overlay->overlay == NULL) { |
|
173 |
++ pr_err("%s: failed to unflatten tree\n", __func__); |
|
174 |
++ err = -EINVAL; |
|
175 |
++ goto out_err; |
|
176 |
++ } |
|
177 |
++ pr_debug("%s: unflattened OK\n", __func__); |
|
178 |
++ |
|
179 |
++ /* mark it as detached */ |
|
180 |
++ of_node_set_flag(overlay->overlay, OF_DETACHED); |
|
181 |
++ |
|
182 |
++ /* perform resolution */ |
|
183 |
++ err = of_resolve_phandles(overlay->overlay); |
|
184 |
++ if (err != 0) { |
|
185 |
++ pr_err("%s: Failed to resolve tree\n", __func__); |
|
186 |
++ goto out_err; |
|
187 |
++ } |
|
188 |
++ pr_debug("%s: resolved OK\n", __func__); |
|
189 |
++ |
|
190 |
++ err = of_overlay_apply(overlay->overlay, &overlay->ov_id); |
|
191 |
++ if (err < 0) { |
|
192 |
++ pr_err("%s: Failed to create overlay (err=%d)\n", |
|
193 |
++ __func__, err); |
|
194 |
++ goto out_err; |
|
195 |
++ } |
|
196 |
++ |
|
197 |
++out_err: |
|
198 |
++ return err; |
|
199 |
++} |
|
200 |
++ |
|
201 |
++static inline struct cfs_overlay_item *to_cfs_overlay_item( |
|
202 |
++ struct config_item *item) |
|
203 |
++{ |
|
204 |
++ return item ? container_of(item, struct cfs_overlay_item, item) : NULL; |
|
205 |
++} |
|
206 |
++ |
|
207 |
++static ssize_t cfs_overlay_item_path_show(struct config_item *item, |
|
208 |
++ char *page) |
|
209 |
++{ |
|
210 |
++ struct cfs_overlay_item *overlay = to_cfs_overlay_item(item); |
|
211 |
++ return sprintf(page, "%s\n", overlay->path); |
|
212 |
++} |
|
213 |
++ |
|
214 |
++static ssize_t cfs_overlay_item_path_store(struct config_item *item, |
|
215 |
++ const char *page, size_t count) |
|
216 |
++{ |
|
217 |
++ struct cfs_overlay_item *overlay = to_cfs_overlay_item(item); |
|
218 |
++ const char *p = page; |
|
219 |
++ char *s; |
|
220 |
++ int err; |
|
221 |
++ |
|
222 |
++ /* if it's set do not allow changes */ |
|
223 |
++ if (overlay->path[0] != '\0' || overlay->dtbo_size > 0) |
|
224 |
++ return -EPERM; |
|
225 |
++ |
|
226 |
++ /* copy to path buffer (and make sure it's always zero terminated */ |
|
227 |
++ count = snprintf(overlay->path, sizeof(overlay->path) - 1, "%s", p); |
|
228 |
++ overlay->path[sizeof(overlay->path) - 1] = '\0'; |
|
229 |
++ |
|
230 |
++ /* strip trailing newlines */ |
|
231 |
++ s = overlay->path + strlen(overlay->path); |
|
232 |
++ while (s > overlay->path && *--s == '\n') |
|
233 |
++ *s = '\0'; |
|
234 |
++ |
|
235 |
++ pr_debug("%s: path is '%s'\n", __func__, overlay->path); |
|
236 |
++ |
|
237 |
++ err = request_firmware(&overlay->fw, overlay->path, NULL); |
|
238 |
++ if (err != 0) |
|
239 |
++ goto out_err; |
|
240 |
++ |
|
241 |
++ err = create_overlay(overlay, (void *)overlay->fw->data); |
|
242 |
++ if (err != 0) |
|
243 |
++ goto out_err; |
|
244 |
++ |
|
245 |
++ return count; |
|
246 |
++ |
|
247 |
++out_err: |
|
248 |
++ |
|
249 |
++ release_firmware(overlay->fw); |
|
250 |
++ overlay->fw = NULL; |
|
251 |
++ |
|
252 |
++ overlay->path[0] = '\0'; |
|
253 |
++ return err; |
|
254 |
++} |
|
255 |
++ |
|
256 |
++static ssize_t cfs_overlay_item_status_show(struct config_item *item, |
|
257 |
++ char *page) |
|
258 |
++{ |
|
259 |
++ struct cfs_overlay_item *overlay = to_cfs_overlay_item(item); |
|
260 |
++ |
|
261 |
++ return sprintf(page, "%s\n", |
|
262 |
++ overlay->ov_id >= 0 ? "applied" : "unapplied"); |
|
263 |
++} |
|
264 |
++ |
|
265 |
++CONFIGFS_ATTR(cfs_overlay_item_, path); |
|
266 |
++CONFIGFS_ATTR_RO(cfs_overlay_item_, status); |
|
267 |
++ |
|
268 |
++static struct configfs_attribute *cfs_overlay_attrs[] = { |
|
269 |
++ &cfs_overlay_item_attr_path, |
|
270 |
++ &cfs_overlay_item_attr_status, |
|
271 |
++ NULL, |
|
272 |
++}; |
|
273 |
++ |
|
274 |
++ssize_t cfs_overlay_item_dtbo_read(struct config_item *item, |
|
275 |
++ void *buf, size_t max_count) |
|
276 |
++{ |
|
277 |
++ struct cfs_overlay_item *overlay = to_cfs_overlay_item(item); |
|
278 |
++ |
|
279 |
++ pr_debug("%s: buf=%p max_count=%zu\n", __func__, |
|
280 |
++ buf, max_count); |
|
281 |
++ |
|
282 |
++ if (overlay->dtbo == NULL) |
|
283 |
++ return 0; |
|
284 |
++ |
|
285 |
++ /* copy if buffer provided */ |
|
286 |
++ if (buf != NULL) { |
|
287 |
++ /* the buffer must be large enough */ |
|
288 |
++ if (overlay->dtbo_size > max_count) |
|
289 |
++ return -ENOSPC; |
|
290 |
++ |
|
291 |
++ memcpy(buf, overlay->dtbo, overlay->dtbo_size); |
|
292 |
++ } |
|
293 |
++ |
|
294 |
++ return overlay->dtbo_size; |
|
295 |
++} |
|
296 |
++ |
|
297 |
++ssize_t cfs_overlay_item_dtbo_write(struct config_item *item, |
|
298 |
++ const void *buf, size_t count) |
|
299 |
++{ |
|
300 |
++ struct cfs_overlay_item *overlay = to_cfs_overlay_item(item); |
|
301 |
++ int err; |
|
302 |
++ |
|
303 |
++ /* if it's set do not allow changes */ |
|
304 |
++ if (overlay->path[0] != '\0' || overlay->dtbo_size > 0) |
|
305 |
++ return -EPERM; |
|
306 |
++ |
|
307 |
++ /* copy the contents */ |
|
308 |
++ overlay->dtbo = kmemdup(buf, count, GFP_KERNEL); |
|
309 |
++ if (overlay->dtbo == NULL) |
|
310 |
++ return -ENOMEM; |
|
311 |
++ |
|
312 |
++ overlay->dtbo_size = count; |
|
313 |
++ |
|
314 |
++ err = create_overlay(overlay, overlay->dtbo); |
|
315 |
++ if (err != 0) |
|
316 |
++ goto out_err; |
|
317 |
++ |
|
318 |
++ return count; |
|
319 |
++ |
|
320 |
++out_err: |
|
321 |
++ kfree(overlay->dtbo); |
|
322 |
++ overlay->dtbo = NULL; |
|
323 |
++ overlay->dtbo_size = 0; |
|
324 |
++ |
|
325 |
++ return err; |
|
326 |
++} |
|
327 |
++ |
|
328 |
++CONFIGFS_BIN_ATTR(cfs_overlay_item_, dtbo, NULL, SZ_1M); |
|
329 |
++ |
|
330 |
++static struct configfs_bin_attribute *cfs_overlay_bin_attrs[] = { |
|
331 |
++ &cfs_overlay_item_attr_dtbo, |
|
332 |
++ NULL, |
|
333 |
++}; |
|
334 |
++ |
|
335 |
++static void cfs_overlay_release(struct config_item *item) |
|
336 |
++{ |
|
337 |
++ struct cfs_overlay_item *overlay = to_cfs_overlay_item(item); |
|
338 |
++ |
|
339 |
++ if (overlay->ov_id >= 0) |
|
340 |
++ of_overlay_remove(&overlay->ov_id); |
|
341 |
++ if (overlay->fw) |
|
342 |
++ release_firmware(overlay->fw); |
|
343 |
++ /* kfree with NULL is safe */ |
|
344 |
++ kfree(overlay->dtbo); |
|
345 |
++ kfree(overlay); |
|
346 |
++} |
|
347 |
++ |
|
348 |
++static struct configfs_item_operations cfs_overlay_item_ops = { |
|
349 |
++ .release = cfs_overlay_release, |
|
350 |
++}; |
|
351 |
++ |
|
352 |
++static struct config_item_type cfs_overlay_type = { |
|
353 |
++ .ct_item_ops = &cfs_overlay_item_ops, |
|
354 |
++ .ct_attrs = cfs_overlay_attrs, |
|
355 |
++ .ct_bin_attrs = cfs_overlay_bin_attrs, |
|
356 |
++ .ct_owner = THIS_MODULE, |
|
357 |
++}; |
|
358 |
++ |
|
359 |
++static struct config_item *cfs_overlay_group_make_item( |
|
360 |
++ struct config_group *group, const char *name) |
|
361 |
++{ |
|
362 |
++ struct cfs_overlay_item *overlay; |
|
363 |
++ |
|
364 |
++ overlay = kzalloc(sizeof(*overlay), GFP_KERNEL); |
|
365 |
++ if (!overlay) |
|
366 |
++ return ERR_PTR(-ENOMEM); |
|
367 |
++ overlay->ov_id = -1; |
|
368 |
++ |
|
369 |
++ config_item_init_type_name(&overlay->item, name, &cfs_overlay_type); |
|
370 |
++ return &overlay->item; |
|
371 |
++} |
|
372 |
++ |
|
373 |
++static void cfs_overlay_group_drop_item(struct config_group *group, |
|
374 |
++ struct config_item *item) |
|
375 |
++{ |
|
376 |
++ struct cfs_overlay_item *overlay = to_cfs_overlay_item(item); |
|
377 |
++ |
|
378 |
++ config_item_put(&overlay->item); |
|
379 |
++} |
|
380 |
++ |
|
381 |
++static struct configfs_group_operations overlays_ops = { |
|
382 |
++ .make_item = cfs_overlay_group_make_item, |
|
383 |
++ .drop_item = cfs_overlay_group_drop_item, |
|
384 |
++}; |
|
385 |
++ |
|
386 |
++static struct config_item_type overlays_type = { |
|
387 |
++ .ct_group_ops = &overlays_ops, |
|
388 |
++ .ct_owner = THIS_MODULE, |
|
389 |
++}; |
|
390 |
++ |
|
391 |
++static struct configfs_group_operations of_cfs_ops = { |
|
392 |
++ /* empty - we don't allow anything to be created */ |
|
393 |
++}; |
|
394 |
++ |
|
395 |
++static struct config_item_type of_cfs_type = { |
|
396 |
++ .ct_group_ops = &of_cfs_ops, |
|
397 |
++ .ct_owner = THIS_MODULE, |
|
398 |
++}; |
|
399 |
++ |
|
400 |
++struct config_group of_cfs_overlay_group; |
|
401 |
++ |
|
402 |
++static struct configfs_subsystem of_cfs_subsys = { |
|
403 |
++ .su_group = { |
|
404 |
++ .cg_item = { |
|
405 |
++ .ci_namebuf = "device-tree", |
|
406 |
++ .ci_type = &of_cfs_type, |
|
407 |
++ }, |
|
408 |
++ }, |
|
409 |
++ .su_mutex = __MUTEX_INITIALIZER(of_cfs_subsys.su_mutex), |
|
410 |
++}; |
|
411 |
++ |
|
412 |
++static int __init of_cfs_init(void) |
|
413 |
++{ |
|
414 |
++ int ret; |
|
415 |
++ |
|
416 |
++ pr_info("%s\n", __func__); |
|
417 |
++ |
|
418 |
++ config_group_init(&of_cfs_subsys.su_group); |
|
419 |
++ config_group_init_type_name(&of_cfs_overlay_group, "overlays", |
|
420 |
++ &overlays_type); |
|
421 |
++ configfs_add_default_group(&of_cfs_overlay_group, |
|
422 |
++ &of_cfs_subsys.su_group); |
|
423 |
++ |
|
424 |
++ ret = configfs_register_subsystem(&of_cfs_subsys); |
|
425 |
++ if (ret != 0) { |
|
426 |
++ pr_err("%s: failed to register subsys\n", __func__); |
|
427 |
++ goto out; |
|
428 |
++ } |
|
429 |
++ pr_info("%s: OK\n", __func__); |
|
430 |
++out: |
|
431 |
++ return ret; |
|
432 |
++} |
|
433 |
++late_initcall(of_cfs_init); |
|
434 |
+-- |
|
435 |
+2.7.4 |
|
436 |
+ |
0 | 437 |
new file mode 100644 |
... | ... |
@@ -0,0 +1,120 @@ |
0 |
+From d52d91b920d4b6ae17adc42375649f1ae190006b Mon Sep 17 00:00:00 2001 |
|
1 |
+From: Phil Elwell <phil@raspberrypi.org> |
|
2 |
+Date: Thu, 14 Jun 2018 15:07:26 +0100 |
|
3 |
+Subject: [PATCH] of: configfs: Use of_overlay_fdt_apply API call |
|
4 |
+ |
|
5 |
+The published API to the dynamic overlay application mechanism now |
|
6 |
+takes a Flattened Device Tree blob as input so that it can manage the |
|
7 |
+lifetime of the unflattened tree. Conveniently, the new API call - |
|
8 |
+of_overlay_fdt_apply - is virtually a drop-in replacement for |
|
9 |
+create_overlay, which can now be deleted. |
|
10 |
+ |
|
11 |
+Signed-off-by: Phil Elwell <phil@raspberrypi.org> |
|
12 |
+Signed-off-by: Ajay Kaher <akaher@vmware.com> |
|
13 |
+--- |
|
14 |
+ drivers/of/configfs.c | 47 +++++++---------------------------------------- |
|
15 |
+ 1 file changed, 7 insertions(+), 40 deletions(-) |
|
16 |
+ |
|
17 |
+diff --git a/drivers/of/configfs.c b/drivers/of/configfs.c |
|
18 |
+index 178f062..ac04301 100644 |
|
19 |
+--- a/drivers/of/configfs.c |
|
20 |
+@@ -40,41 +40,6 @@ struct cfs_overlay_item { |
|
21 |
+ int dtbo_size; |
|
22 |
+ }; |
|
23 |
+ |
|
24 |
+-static int create_overlay(struct cfs_overlay_item *overlay, void *blob) |
|
25 |
+-{ |
|
26 |
+- int err; |
|
27 |
+- |
|
28 |
+- /* unflatten the tree */ |
|
29 |
+- of_fdt_unflatten_tree(blob, NULL, &overlay->overlay); |
|
30 |
+- if (overlay->overlay == NULL) { |
|
31 |
+- pr_err("%s: failed to unflatten tree\n", __func__); |
|
32 |
+- err = -EINVAL; |
|
33 |
+- goto out_err; |
|
34 |
+- } |
|
35 |
+- pr_debug("%s: unflattened OK\n", __func__); |
|
36 |
+- |
|
37 |
+- /* mark it as detached */ |
|
38 |
+- of_node_set_flag(overlay->overlay, OF_DETACHED); |
|
39 |
+- |
|
40 |
+- /* perform resolution */ |
|
41 |
+- err = of_resolve_phandles(overlay->overlay); |
|
42 |
+- if (err != 0) { |
|
43 |
+- pr_err("%s: Failed to resolve tree\n", __func__); |
|
44 |
+- goto out_err; |
|
45 |
+- } |
|
46 |
+- pr_debug("%s: resolved OK\n", __func__); |
|
47 |
+- |
|
48 |
+- err = of_overlay_apply(overlay->overlay, &overlay->ov_id); |
|
49 |
+- if (err < 0) { |
|
50 |
+- pr_err("%s: Failed to create overlay (err=%d)\n", |
|
51 |
+- __func__, err); |
|
52 |
+- goto out_err; |
|
53 |
+- } |
|
54 |
+- |
|
55 |
+-out_err: |
|
56 |
+- return err; |
|
57 |
+-} |
|
58 |
+- |
|
59 |
+ static inline struct cfs_overlay_item *to_cfs_overlay_item( |
|
60 |
+ struct config_item *item) |
|
61 |
+ { |
|
62 |
+@@ -115,7 +80,8 @@ static ssize_t cfs_overlay_item_path_store(struct config_item *item, |
|
63 |
+ if (err != 0) |
|
64 |
+ goto out_err; |
|
65 |
+ |
|
66 |
+- err = create_overlay(overlay, (void *)overlay->fw->data); |
|
67 |
++ err = of_overlay_fdt_apply((void *)overlay->fw->data, |
|
68 |
++ (u32)overlay->fw->size, &overlay->ov_id); |
|
69 |
+ if (err != 0) |
|
70 |
+ goto out_err; |
|
71 |
+ |
|
72 |
+@@ -136,7 +102,7 @@ static ssize_t cfs_overlay_item_status_show(struct config_item *item, |
|
73 |
+ struct cfs_overlay_item *overlay = to_cfs_overlay_item(item); |
|
74 |
+ |
|
75 |
+ return sprintf(page, "%s\n", |
|
76 |
+- overlay->ov_id >= 0 ? "applied" : "unapplied"); |
|
77 |
++ overlay->ov_id > 0 ? "applied" : "unapplied"); |
|
78 |
+ } |
|
79 |
+ |
|
80 |
+ CONFIGFS_ATTR(cfs_overlay_item_, path); |
|
81 |
+@@ -188,7 +154,8 @@ ssize_t cfs_overlay_item_dtbo_write(struct config_item *item, |
|
82 |
+ |
|
83 |
+ overlay->dtbo_size = count; |
|
84 |
+ |
|
85 |
+- err = create_overlay(overlay, overlay->dtbo); |
|
86 |
++ err = of_overlay_fdt_apply(overlay->dtbo, overlay->dtbo_size, |
|
87 |
++ &overlay->ov_id); |
|
88 |
+ if (err != 0) |
|
89 |
+ goto out_err; |
|
90 |
+ |
|
91 |
+@@ -198,6 +165,7 @@ ssize_t cfs_overlay_item_dtbo_write(struct config_item *item, |
|
92 |
+ kfree(overlay->dtbo); |
|
93 |
+ overlay->dtbo = NULL; |
|
94 |
+ overlay->dtbo_size = 0; |
|
95 |
++ overlay->ov_id = 0; |
|
96 |
+ |
|
97 |
+ return err; |
|
98 |
+ } |
|
99 |
+@@ -213,7 +181,7 @@ static void cfs_overlay_release(struct config_item *item) |
|
100 |
+ { |
|
101 |
+ struct cfs_overlay_item *overlay = to_cfs_overlay_item(item); |
|
102 |
+ |
|
103 |
+- if (overlay->ov_id >= 0) |
|
104 |
++ if (overlay->ov_id > 0) |
|
105 |
+ of_overlay_remove(&overlay->ov_id); |
|
106 |
+ if (overlay->fw) |
|
107 |
+ release_firmware(overlay->fw); |
|
108 |
+@@ -241,7 +209,6 @@ static struct config_item *cfs_overlay_group_make_item( |
|
109 |
+ overlay = kzalloc(sizeof(*overlay), GFP_KERNEL); |
|
110 |
+ if (!overlay) |
|
111 |
+ return ERR_PTR(-ENOMEM); |
|
112 |
+- overlay->ov_id = -1; |
|
113 |
+ |
|
114 |
+ config_item_init_type_name(&overlay->item, name, &cfs_overlay_type); |
|
115 |
+ return &overlay->item; |
|
116 |
+-- |
|
117 |
+2.7.4 |
|
118 |
+ |
... | ... |
@@ -2,7 +2,7 @@ |
2 | 2 |
Summary: Kernel |
3 | 3 |
Name: linux |
4 | 4 |
Version: 4.19.52 |
5 |
-Release: 6%{?kat_build:.%kat_build}%{?dist} |
|
5 |
+Release: 7%{?kat_build:.%kat_build}%{?dist} |
|
6 | 6 |
License: GPLv2 |
7 | 7 |
URL: http://www.kernel.org/ |
8 | 8 |
Group: System Environment/Kernel |
... | ... |
@@ -62,6 +62,10 @@ Patch38: 0001-ipv6_sockglue-Fix-a-missing-check-bug-in-ip6_ra_cont.patch |
62 | 62 |
Patch39: 0001-clk-sunxi-fix-a-missing-check-bug-in-sunxi_divs_clk_.patch |
63 | 63 |
|
64 | 64 |
%ifarch aarch64 |
65 |
+# Rpi of_configfs patches |
|
66 |
+Patch40: 0001-OF-DT-Overlay-configfs-interface.patch |
|
67 |
+Patch41: 0002-of-configfs-Use-of_overlay_fdt_apply-API-call.patch |
|
68 |
+ |
|
65 | 69 |
# NXP LS1012a FRWY patches |
66 | 70 |
Patch51: 0001-staging-fsl_ppfe-eth-header-files-for-pfe-driver.patch |
67 | 71 |
Patch52: 0002-staging-fsl_ppfe-eth-introduce-pfe-driver.patch |
... | ... |
@@ -210,6 +214,10 @@ Kernel Device Tree Blob files for NXP ls1012a FRWY board |
210 | 210 |
%patch39 -p1 |
211 | 211 |
|
212 | 212 |
%ifarch aarch64 |
213 |
+# Rpi of_configfs patches |
|
214 |
+%patch40 -p1 |
|
215 |
+%patch41 -p1 |
|
216 |
+ |
|
213 | 217 |
# NXP FSL_PPFE Driver patches |
214 | 218 |
%patch51 -p1 |
215 | 219 |
%patch52 -p1 |
... | ... |
@@ -467,6 +475,8 @@ ln -sf %{name}-%{uname_r}.cfg /boot/photon.cfg |
467 | 467 |
%endif |
468 | 468 |
|
469 | 469 |
%changelog |
470 |
+* Tue Jul 30 2019 Ajay Kaher <akaher@vmware.com> 4.19.52-7 |
|
471 |
+- Added of_configfs patches to dynamic load Overlays. |
|
470 | 472 |
* Thu Jul 25 2019 Keerthana K <keerthanak@vmware.com> 4.19.52-6 |
471 | 473 |
- Fix postun scriplet. |
472 | 474 |
* Thu Jul 11 2019 Keerthana K <keerthanak@vmware.com> 4.19.52-5 |