]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blob - drivers/of/overlay.c
net: ethernet: ti: ale: disable ale from stop()
[mirror_ubuntu-bionic-kernel.git] / drivers / of / overlay.c
1 /*
2 * Functions for working with device tree overlays
3 *
4 * Copyright (C) 2012 Pantelis Antoniou <panto@antoniou-consulting.com>
5 * Copyright (C) 2012 Texas Instruments Inc.
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * version 2 as published by the Free Software Foundation.
10 */
11
12 #define pr_fmt(fmt) "OF: overlay: " fmt
13
14 #include <linux/kernel.h>
15 #include <linux/module.h>
16 #include <linux/of.h>
17 #include <linux/of_device.h>
18 #include <linux/string.h>
19 #include <linux/ctype.h>
20 #include <linux/errno.h>
21 #include <linux/slab.h>
22 #include <linux/err.h>
23 #include <linux/idr.h>
24
25 #include "of_private.h"
26
27 /**
28 * struct target - info about current target node as recursing through overlay
29 * @np: node where current level of overlay will be applied
30 * @in_livetree: @np is a node in the live devicetree
31 *
32 * Used in the algorithm to create the portion of a changeset that describes
33 * an overlay fragment, which is a devicetree subtree. Initially @np is a node
34 * in the live devicetree where the overlay subtree is targeted to be grafted
35 * into. When recursing to the next level of the overlay subtree, the target
36 * also recurses to the next level of the live devicetree, as long as overlay
37 * subtree node also exists in the live devicetree. When a node in the overlay
38 * subtree does not exist at the same level in the live devicetree, target->np
39 * points to a newly allocated node, and all subsequent targets in the subtree
40 * will be newly allocated nodes.
41 */
42 struct target {
43 struct device_node *np;
44 bool in_livetree;
45 };
46
47 /**
48 * struct fragment - info about fragment nodes in overlay expanded device tree
49 * @target: target of the overlay operation
50 * @overlay: pointer to the __overlay__ node
51 */
52 struct fragment {
53 struct device_node *target;
54 struct device_node *overlay;
55 };
56
57 /**
58 * struct overlay_changeset
59 * @ovcs_list: list on which we are located
60 * @overlay_tree: expanded device tree that contains the fragment nodes
61 * @count: count of fragment structures
62 * @fragments: fragment nodes in the overlay expanded device tree
63 * @symbols_fragment: last element of @fragments[] is the __symbols__ node
64 * @cset: changeset to apply fragments to live device tree
65 */
66 struct overlay_changeset {
67 int id;
68 struct list_head ovcs_list;
69 struct device_node *overlay_tree;
70 int count;
71 struct fragment *fragments;
72 bool symbols_fragment;
73 struct of_changeset cset;
74 };
75
76 /* flags are sticky - once set, do not reset */
77 static int devicetree_state_flags;
78 #define DTSF_APPLY_FAIL 0x01
79 #define DTSF_REVERT_FAIL 0x02
80
81 /*
82 * If a changeset apply or revert encounters an error, an attempt will
83 * be made to undo partial changes, but may fail. If the undo fails
84 * we do not know the state of the devicetree.
85 */
86 static int devicetree_corrupt(void)
87 {
88 return devicetree_state_flags &
89 (DTSF_APPLY_FAIL | DTSF_REVERT_FAIL);
90 }
91
92 static int build_changeset_next_level(struct overlay_changeset *ovcs,
93 struct target *target, const struct device_node *overlay_node);
94
95 /*
96 * of_resolve_phandles() finds the largest phandle in the live tree.
97 * of_overlay_apply() may add a larger phandle to the live tree.
98 * Do not allow race between two overlays being applied simultaneously:
99 * mutex_lock(&of_overlay_phandle_mutex)
100 * of_resolve_phandles()
101 * of_overlay_apply()
102 * mutex_unlock(&of_overlay_phandle_mutex)
103 */
104 static DEFINE_MUTEX(of_overlay_phandle_mutex);
105
106 void of_overlay_mutex_lock(void)
107 {
108 mutex_lock(&of_overlay_phandle_mutex);
109 }
110
111 void of_overlay_mutex_unlock(void)
112 {
113 mutex_unlock(&of_overlay_phandle_mutex);
114 }
115
116
117 static LIST_HEAD(ovcs_list);
118 static DEFINE_IDR(ovcs_idr);
119
120 static BLOCKING_NOTIFIER_HEAD(overlay_notify_chain);
121
122 int of_overlay_notifier_register(struct notifier_block *nb)
123 {
124 return blocking_notifier_chain_register(&overlay_notify_chain, nb);
125 }
126 EXPORT_SYMBOL_GPL(of_overlay_notifier_register);
127
128 int of_overlay_notifier_unregister(struct notifier_block *nb)
129 {
130 return blocking_notifier_chain_unregister(&overlay_notify_chain, nb);
131 }
132 EXPORT_SYMBOL_GPL(of_overlay_notifier_unregister);
133
134 static char *of_overlay_action_name[] = {
135 "pre-apply",
136 "post-apply",
137 "pre-remove",
138 "post-remove",
139 };
140
141 static int overlay_notify(struct overlay_changeset *ovcs,
142 enum of_overlay_notify_action action)
143 {
144 struct of_overlay_notify_data nd;
145 int i, ret;
146
147 for (i = 0; i < ovcs->count; i++) {
148 struct fragment *fragment = &ovcs->fragments[i];
149
150 nd.target = fragment->target;
151 nd.overlay = fragment->overlay;
152
153 ret = blocking_notifier_call_chain(&overlay_notify_chain,
154 action, &nd);
155 if (ret == NOTIFY_OK || ret == NOTIFY_STOP)
156 return 0;
157 if (ret) {
158 ret = notifier_to_errno(ret);
159 pr_err("overlay changeset %s notifier error %d, target: %pOF\n",
160 of_overlay_action_name[action], ret, nd.target);
161 return ret;
162 }
163 }
164
165 return 0;
166 }
167
168 /*
169 * The values of properties in the "/__symbols__" node are paths in
170 * the ovcs->overlay_tree. When duplicating the properties, the paths
171 * need to be adjusted to be the correct path for the live device tree.
172 *
173 * The paths refer to a node in the subtree of a fragment node's "__overlay__"
174 * node, for example "/fragment@0/__overlay__/symbol_path_tail",
175 * where symbol_path_tail can be a single node or it may be a multi-node path.
176 *
177 * The duplicated property value will be modified by replacing the
178 * "/fragment_name/__overlay/" portion of the value with the target
179 * path from the fragment node.
180 */
181 static struct property *dup_and_fixup_symbol_prop(
182 struct overlay_changeset *ovcs, const struct property *prop)
183 {
184 struct fragment *fragment;
185 struct property *new_prop;
186 struct device_node *fragment_node;
187 struct device_node *overlay_node;
188 const char *path;
189 const char *path_tail;
190 const char *target_path;
191 int k;
192 int overlay_name_len;
193 int path_len;
194 int path_tail_len;
195 int target_path_len;
196
197 if (!prop->value)
198 return NULL;
199 if (strnlen(prop->value, prop->length) >= prop->length)
200 return NULL;
201 path = prop->value;
202 path_len = strlen(path);
203
204 if (path_len < 1)
205 return NULL;
206 fragment_node = __of_find_node_by_path(ovcs->overlay_tree, path + 1);
207 overlay_node = __of_find_node_by_path(fragment_node, "__overlay__/");
208 of_node_put(fragment_node);
209 of_node_put(overlay_node);
210
211 for (k = 0; k < ovcs->count; k++) {
212 fragment = &ovcs->fragments[k];
213 if (fragment->overlay == overlay_node)
214 break;
215 }
216 if (k >= ovcs->count)
217 return NULL;
218
219 overlay_name_len = snprintf(NULL, 0, "%pOF", fragment->overlay);
220
221 if (overlay_name_len > path_len)
222 return NULL;
223 path_tail = path + overlay_name_len;
224 path_tail_len = strlen(path_tail);
225
226 target_path = kasprintf(GFP_KERNEL, "%pOF", fragment->target);
227 if (!target_path)
228 return NULL;
229 target_path_len = strlen(target_path);
230
231 new_prop = kzalloc(sizeof(*new_prop), GFP_KERNEL);
232 if (!new_prop)
233 goto err_free_target_path;
234
235 new_prop->name = kstrdup(prop->name, GFP_KERNEL);
236 new_prop->length = target_path_len + path_tail_len + 1;
237 new_prop->value = kzalloc(new_prop->length, GFP_KERNEL);
238 if (!new_prop->name || !new_prop->value)
239 goto err_free_new_prop;
240
241 strcpy(new_prop->value, target_path);
242 strcpy(new_prop->value + target_path_len, path_tail);
243
244 of_property_set_flag(new_prop, OF_DYNAMIC);
245
246 return new_prop;
247
248 err_free_new_prop:
249 kfree(new_prop->name);
250 kfree(new_prop->value);
251 kfree(new_prop);
252 err_free_target_path:
253 kfree(target_path);
254
255 return NULL;
256 }
257
258 /**
259 * add_changeset_property() - add @overlay_prop to overlay changeset
260 * @ovcs: overlay changeset
261 * @target: where @overlay_prop will be placed
262 * @overlay_prop: property to add or update, from overlay tree
263 * @is_symbols_prop: 1 if @overlay_prop is from node "/__symbols__"
264 *
265 * If @overlay_prop does not already exist in live devicetree, add changeset
266 * entry to add @overlay_prop in @target, else add changeset entry to update
267 * value of @overlay_prop.
268 *
269 * @target may be either in the live devicetree or in a new subtree that
270 * is contained in the changeset.
271 *
272 * Some special properties are not added or updated (no error returned):
273 * "name", "phandle", "linux,phandle".
274 *
275 * Properties "#address-cells" and "#size-cells" are not updated if they
276 * are already in the live tree, but if present in the live tree, the values
277 * in the overlay must match the values in the live tree.
278 *
279 * Update of property in symbols node is not allowed.
280 *
281 * Returns 0 on success, -ENOMEM if memory allocation failure, or -EINVAL if
282 * invalid @overlay.
283 */
284 static int add_changeset_property(struct overlay_changeset *ovcs,
285 struct target *target, struct property *overlay_prop,
286 bool is_symbols_prop)
287 {
288 struct property *new_prop = NULL, *prop;
289 int ret = 0;
290
291 if (target->in_livetree)
292 if (!of_prop_cmp(overlay_prop->name, "name") ||
293 !of_prop_cmp(overlay_prop->name, "phandle") ||
294 !of_prop_cmp(overlay_prop->name, "linux,phandle"))
295 return 0;
296
297 if (target->in_livetree)
298 prop = of_find_property(target->np, overlay_prop->name, NULL);
299 else
300 prop = NULL;
301
302 if (prop) {
303 if (!of_prop_cmp(prop->name, "#address-cells")) {
304 if (!of_prop_val_eq(prop, overlay_prop)) {
305 pr_err("ERROR: changing value of #address-cells is not allowed in %pOF\n",
306 target->np);
307 ret = -EINVAL;
308 }
309 return ret;
310
311 } else if (!of_prop_cmp(prop->name, "#size-cells")) {
312 if (!of_prop_val_eq(prop, overlay_prop)) {
313 pr_err("ERROR: changing value of #size-cells is not allowed in %pOF\n",
314 target->np);
315 ret = -EINVAL;
316 }
317 return ret;
318 }
319 }
320
321 if (is_symbols_prop) {
322 if (prop)
323 return -EINVAL;
324 new_prop = dup_and_fixup_symbol_prop(ovcs, overlay_prop);
325 } else {
326 new_prop = __of_prop_dup(overlay_prop, GFP_KERNEL);
327 }
328
329 if (!new_prop)
330 return -ENOMEM;
331
332 if (!prop) {
333 if (!target->in_livetree) {
334 new_prop->next = target->np->deadprops;
335 target->np->deadprops = new_prop;
336 }
337 ret = of_changeset_add_property(&ovcs->cset, target->np,
338 new_prop);
339 } else {
340 ret = of_changeset_update_property(&ovcs->cset, target->np,
341 new_prop);
342 }
343
344 if (!of_node_check_flag(target->np, OF_OVERLAY))
345 pr_err("WARNING: memory leak will occur if overlay removed, property: %pOF/%s\n",
346 target->np, new_prop->name);
347
348 if (ret) {
349 kfree(new_prop->name);
350 kfree(new_prop->value);
351 kfree(new_prop);
352 }
353 return ret;
354 }
355
356 /**
357 * add_changeset_node() - add @node (and children) to overlay changeset
358 * @ovcs: overlay changeset
359 * @target: where @node will be placed in live tree or changeset
360 * @node: node from within overlay device tree fragment
361 *
362 * If @node does not already exist in @target, add changeset entry
363 * to add @node in @target.
364 *
365 * If @node already exists in @target, and the existing node has
366 * a phandle, the overlay node is not allowed to have a phandle.
367 *
368 * If @node has child nodes, add the children recursively via
369 * build_changeset_next_level().
370 *
371 * NOTE: Multiple mods of created nodes not supported.
372 * If more than one fragment contains a node that does not already exist
373 * in the live tree, then for each fragment of_changeset_attach_node()
374 * will add a changeset entry to add the node. When the changeset is
375 * applied, __of_attach_node() will attach the node twice (once for
376 * each fragment). At this point the device tree will be corrupted.
377 *
378 * TODO: add integrity check to ensure that multiple fragments do not
379 * create the same node.
380 *
381 * Returns 0 on success, -ENOMEM if memory allocation failure, or -EINVAL if
382 * invalid @overlay.
383 */
384 static int add_changeset_node(struct overlay_changeset *ovcs,
385 struct target *target, struct device_node *node)
386 {
387 const char *node_kbasename;
388 const __be32 *phandle;
389 struct device_node *tchild;
390 struct target target_child;
391 int ret = 0, size;
392
393 node_kbasename = kbasename(node->full_name);
394
395 for_each_child_of_node(target->np, tchild)
396 if (!of_node_cmp(node_kbasename, kbasename(tchild->full_name)))
397 break;
398
399 if (!tchild) {
400 tchild = __of_node_dup(NULL, "%pOF/%s",
401 target->np, node_kbasename);
402 if (!tchild)
403 return -ENOMEM;
404
405 tchild->parent = target->np;
406 tchild->name = __of_get_property(node, "name", NULL);
407 tchild->type = __of_get_property(node, "device_type", NULL);
408
409 if (!tchild->name)
410 tchild->name = "<NULL>";
411 if (!tchild->type)
412 tchild->type = "<NULL>";
413
414 /* ignore obsolete "linux,phandle" */
415 phandle = __of_get_property(node, "phandle", &size);
416 if (phandle && (size == 4))
417 tchild->phandle = be32_to_cpup(phandle);
418
419 of_node_set_flag(tchild, OF_OVERLAY);
420
421 ret = of_changeset_attach_node(&ovcs->cset, tchild);
422 if (ret)
423 return ret;
424
425 target_child.np = tchild;
426 target_child.in_livetree = false;
427
428 ret = build_changeset_next_level(ovcs, &target_child, node);
429 of_node_put(tchild);
430 return ret;
431 }
432
433 if (node->phandle && tchild->phandle) {
434 ret = -EINVAL;
435 } else {
436 target_child.np = tchild;
437 target_child.in_livetree = target->in_livetree;
438 ret = build_changeset_next_level(ovcs, &target_child, node);
439 }
440 of_node_put(tchild);
441
442 return ret;
443 }
444
445 /**
446 * build_changeset_next_level() - add level of overlay changeset
447 * @ovcs: overlay changeset
448 * @target: where to place @overlay_node in live tree
449 * @overlay_node: node from within an overlay device tree fragment
450 *
451 * Add the properties (if any) and nodes (if any) from @overlay_node to the
452 * @ovcs->cset changeset. If an added node has child nodes, they will
453 * be added recursively.
454 *
455 * Do not allow symbols node to have any children.
456 *
457 * Returns 0 on success, -ENOMEM if memory allocation failure, or -EINVAL if
458 * invalid @overlay_node.
459 */
460 static int build_changeset_next_level(struct overlay_changeset *ovcs,
461 struct target *target, const struct device_node *overlay_node)
462 {
463 struct device_node *child;
464 struct property *prop;
465 int ret;
466
467 for_each_property_of_node(overlay_node, prop) {
468 ret = add_changeset_property(ovcs, target, prop, 0);
469 if (ret) {
470 pr_debug("Failed to apply prop @%pOF/%s, err=%d\n",
471 target->np, prop->name, ret);
472 return ret;
473 }
474 }
475
476 for_each_child_of_node(overlay_node, child) {
477 ret = add_changeset_node(ovcs, target, child);
478 if (ret) {
479 pr_debug("Failed to apply node @%pOF/%pOFn, err=%d\n",
480 target->np, child, ret);
481 of_node_put(child);
482 return ret;
483 }
484 }
485
486 return 0;
487 }
488
489 /*
490 * Add the properties from __overlay__ node to the @ovcs->cset changeset.
491 */
492 static int build_changeset_symbols_node(struct overlay_changeset *ovcs,
493 struct target *target,
494 const struct device_node *overlay_symbols_node)
495 {
496 struct property *prop;
497 int ret;
498
499 for_each_property_of_node(overlay_symbols_node, prop) {
500 ret = add_changeset_property(ovcs, target, prop, 1);
501 if (ret) {
502 pr_debug("Failed to apply prop @%pOF/%s, err=%d\n",
503 target->np, prop->name, ret);
504 return ret;
505 }
506 }
507
508 return 0;
509 }
510
511 /**
512 * build_changeset() - populate overlay changeset in @ovcs from @ovcs->fragments
513 * @ovcs: Overlay changeset
514 *
515 * Create changeset @ovcs->cset to contain the nodes and properties of the
516 * overlay device tree fragments in @ovcs->fragments[]. If an error occurs,
517 * any portions of the changeset that were successfully created will remain
518 * in @ovcs->cset.
519 *
520 * Returns 0 on success, -ENOMEM if memory allocation failure, or -EINVAL if
521 * invalid overlay in @ovcs->fragments[].
522 */
523 static int build_changeset(struct overlay_changeset *ovcs)
524 {
525 struct fragment *fragment;
526 struct target target;
527 int fragments_count, i, ret;
528
529 /*
530 * if there is a symbols fragment in ovcs->fragments[i] it is
531 * the final element in the array
532 */
533 if (ovcs->symbols_fragment)
534 fragments_count = ovcs->count - 1;
535 else
536 fragments_count = ovcs->count;
537
538 for (i = 0; i < fragments_count; i++) {
539 fragment = &ovcs->fragments[i];
540
541 target.np = fragment->target;
542 target.in_livetree = true;
543 ret = build_changeset_next_level(ovcs, &target,
544 fragment->overlay);
545 if (ret) {
546 pr_debug("apply failed '%pOF'\n", fragment->target);
547 return ret;
548 }
549 }
550
551 if (ovcs->symbols_fragment) {
552 fragment = &ovcs->fragments[ovcs->count - 1];
553
554 target.np = fragment->target;
555 target.in_livetree = true;
556 ret = build_changeset_symbols_node(ovcs, &target,
557 fragment->overlay);
558 if (ret) {
559 pr_debug("apply failed '%pOF'\n", fragment->target);
560 return ret;
561 }
562 }
563
564 return 0;
565 }
566
567 /*
568 * Find the target node using a number of different strategies
569 * in order of preference:
570 *
571 * 1) "target" property containing the phandle of the target
572 * 2) "target-path" property containing the path of the target
573 */
574 static struct device_node *find_target(struct device_node *info_node)
575 {
576 const char *path;
577 u32 val;
578 int ret;
579
580 ret = of_property_read_u32(info_node, "target", &val);
581 if (!ret)
582 return of_find_node_by_phandle(val);
583
584 ret = of_property_read_string(info_node, "target-path", &path);
585 if (!ret)
586 return of_find_node_by_path(path);
587
588 pr_err("Failed to find target for node %p (%s)\n",
589 info_node, info_node->name);
590
591 return NULL;
592 }
593
594 /**
595 * init_overlay_changeset() - initialize overlay changeset from overlay tree
596 * @ovcs Overlay changeset to build
597 * @tree: Contains all the overlay fragments and overlay fixup nodes
598 *
599 * Initialize @ovcs. Populate @ovcs->fragments with node information from
600 * the top level of @tree. The relevant top level nodes are the fragment
601 * nodes and the __symbols__ node. Any other top level node will be ignored.
602 *
603 * Returns 0 on success, -ENOMEM if memory allocation failure, -EINVAL if error
604 * detected in @tree, or -ENOSPC if idr_alloc() error.
605 */
606 static int init_overlay_changeset(struct overlay_changeset *ovcs,
607 struct device_node *tree)
608 {
609 struct device_node *node, *overlay_node;
610 struct fragment *fragment;
611 struct fragment *fragments;
612 int cnt, id, ret;
613
614 /*
615 * Warn for some issues. Can not return -EINVAL for these until
616 * of_unittest_apply_overlay() is fixed to pass these checks.
617 */
618 if (!of_node_check_flag(tree, OF_DYNAMIC))
619 pr_debug("%s() tree is not dynamic\n", __func__);
620
621 if (!of_node_check_flag(tree, OF_DETACHED))
622 pr_debug("%s() tree is not detached\n", __func__);
623
624 if (!of_node_is_root(tree))
625 pr_debug("%s() tree is not root\n", __func__);
626
627 ovcs->overlay_tree = tree;
628
629 INIT_LIST_HEAD(&ovcs->ovcs_list);
630
631 of_changeset_init(&ovcs->cset);
632
633 id = idr_alloc(&ovcs_idr, ovcs, 1, 0, GFP_KERNEL);
634 if (id <= 0)
635 return id;
636
637 cnt = 0;
638
639 /* fragment nodes */
640 for_each_child_of_node(tree, node) {
641 overlay_node = of_get_child_by_name(node, "__overlay__");
642 if (overlay_node) {
643 cnt++;
644 of_node_put(overlay_node);
645 }
646 }
647
648 node = of_get_child_by_name(tree, "__symbols__");
649 if (node) {
650 cnt++;
651 of_node_put(node);
652 }
653
654 fragments = kcalloc(cnt, sizeof(*fragments), GFP_KERNEL);
655 if (!fragments) {
656 ret = -ENOMEM;
657 goto err_free_idr;
658 }
659
660 cnt = 0;
661 for_each_child_of_node(tree, node) {
662 overlay_node = of_get_child_by_name(node, "__overlay__");
663 if (!overlay_node)
664 continue;
665
666 fragment = &fragments[cnt];
667 fragment->overlay = overlay_node;
668 fragment->target = find_target(node);
669 if (!fragment->target) {
670 of_node_put(fragment->overlay);
671 ret = -EINVAL;
672 goto err_free_fragments;
673 }
674
675 cnt++;
676 }
677
678 /*
679 * if there is a symbols fragment in ovcs->fragments[i] it is
680 * the final element in the array
681 */
682 node = of_get_child_by_name(tree, "__symbols__");
683 if (node) {
684 ovcs->symbols_fragment = 1;
685 fragment = &fragments[cnt];
686 fragment->overlay = node;
687 fragment->target = of_find_node_by_path("/__symbols__");
688
689 if (!fragment->target) {
690 pr_err("symbols in overlay, but not in live tree\n");
691 ret = -EINVAL;
692 goto err_free_fragments;
693 }
694
695 cnt++;
696 }
697
698 if (!cnt) {
699 ret = -EINVAL;
700 goto err_free_fragments;
701 }
702
703 ovcs->id = id;
704 ovcs->count = cnt;
705 ovcs->fragments = fragments;
706
707 return 0;
708
709 err_free_fragments:
710 kfree(fragments);
711 err_free_idr:
712 idr_remove(&ovcs_idr, id);
713
714 pr_err("%s() failed, ret = %d\n", __func__, ret);
715
716 return ret;
717 }
718
719 static void free_overlay_changeset(struct overlay_changeset *ovcs)
720 {
721 int i;
722
723 if (ovcs->cset.entries.next)
724 of_changeset_destroy(&ovcs->cset);
725
726 if (ovcs->id)
727 idr_remove(&ovcs_idr, ovcs->id);
728
729 for (i = 0; i < ovcs->count; i++) {
730 of_node_put(ovcs->fragments[i].target);
731 of_node_put(ovcs->fragments[i].overlay);
732 }
733 kfree(ovcs->fragments);
734
735 kfree(ovcs);
736 }
737
738 /**
739 * of_overlay_apply() - Create and apply an overlay changeset
740 * @tree: Expanded overlay device tree
741 * @ovcs_id: Pointer to overlay changeset id
742 *
743 * Creates and applies an overlay changeset.
744 *
745 * If an error occurs in a pre-apply notifier, then no changes are made
746 * to the device tree.
747 *
748
749 * A non-zero return value will not have created the changeset if error is from:
750 * - parameter checks
751 * - building the changeset
752 * - overlay changeset pre-apply notifier
753 *
754 * If an error is returned by an overlay changeset pre-apply notifier
755 * then no further overlay changeset pre-apply notifier will be called.
756 *
757 * A non-zero return value will have created the changeset if error is from:
758 * - overlay changeset entry notifier
759 * - overlay changeset post-apply notifier
760 *
761 * If an error is returned by an overlay changeset post-apply notifier
762 * then no further overlay changeset post-apply notifier will be called.
763 *
764 * If more than one notifier returns an error, then the last notifier
765 * error to occur is returned.
766 *
767 * If an error occurred while applying the overlay changeset, then an
768 * attempt is made to revert any changes that were made to the
769 * device tree. If there were any errors during the revert attempt
770 * then the state of the device tree can not be determined, and any
771 * following attempt to apply or remove an overlay changeset will be
772 * refused.
773 *
774 * Returns 0 on success, or a negative error number. Overlay changeset
775 * id is returned to *ovcs_id.
776 */
777
778 int of_overlay_apply(struct device_node *tree, int *ovcs_id)
779 {
780 struct overlay_changeset *ovcs;
781 int ret = 0, ret_revert, ret_tmp;
782
783 *ovcs_id = 0;
784
785 if (devicetree_corrupt()) {
786 pr_err("devicetree state suspect, refuse to apply overlay\n");
787 ret = -EBUSY;
788 goto out;
789 }
790
791 ovcs = kzalloc(sizeof(*ovcs), GFP_KERNEL);
792 if (!ovcs) {
793 ret = -ENOMEM;
794 goto out;
795 }
796
797 of_overlay_mutex_lock();
798 mutex_lock(&of_mutex);
799
800 ret = of_resolve_phandles(tree);
801 if (ret)
802 goto err_free_overlay_changeset;
803
804 ret = init_overlay_changeset(ovcs, tree);
805 if (ret)
806 goto err_free_overlay_changeset;
807
808 ret = overlay_notify(ovcs, OF_OVERLAY_PRE_APPLY);
809 if (ret) {
810 pr_err("overlay changeset pre-apply notify error %d\n", ret);
811 goto err_free_overlay_changeset;
812 }
813
814 ret = build_changeset(ovcs);
815 if (ret)
816 goto err_free_overlay_changeset;
817
818 ret_revert = 0;
819 ret = __of_changeset_apply_entries(&ovcs->cset, &ret_revert);
820 if (ret) {
821 if (ret_revert) {
822 pr_debug("overlay changeset revert error %d\n",
823 ret_revert);
824 devicetree_state_flags |= DTSF_APPLY_FAIL;
825 }
826 goto err_free_overlay_changeset;
827 }
828
829 ret = __of_changeset_apply_notify(&ovcs->cset);
830 if (ret)
831 pr_err("overlay changeset entry notify error %d\n", ret);
832 /* notify failure is not fatal, continue */
833
834 list_add_tail(&ovcs->ovcs_list, &ovcs_list);
835 *ovcs_id = ovcs->id;
836
837 ret_tmp = overlay_notify(ovcs, OF_OVERLAY_POST_APPLY);
838 if (ret_tmp) {
839 pr_err("overlay changeset post-apply notify error %d\n",
840 ret_tmp);
841 if (!ret)
842 ret = ret_tmp;
843 }
844
845 goto out_unlock;
846
847 err_free_overlay_changeset:
848 free_overlay_changeset(ovcs);
849
850 out_unlock:
851 mutex_unlock(&of_mutex);
852 of_overlay_mutex_unlock();
853
854 out:
855 pr_debug("%s() err=%d\n", __func__, ret);
856
857 return ret;
858 }
859 EXPORT_SYMBOL_GPL(of_overlay_apply);
860
861 /*
862 * Find @np in @tree.
863 *
864 * Returns 1 if @np is @tree or is contained in @tree, else 0
865 */
866 static int find_node(struct device_node *tree, struct device_node *np)
867 {
868 struct device_node *child;
869
870 if (tree == np)
871 return 1;
872
873 for_each_child_of_node(tree, child) {
874 if (find_node(child, np)) {
875 of_node_put(child);
876 return 1;
877 }
878 }
879
880 return 0;
881 }
882
883 /*
884 * Is @remove_ce_node a child of, a parent of, or the same as any
885 * node in an overlay changeset more topmost than @remove_ovcs?
886 *
887 * Returns 1 if found, else 0
888 */
889 static int node_overlaps_later_cs(struct overlay_changeset *remove_ovcs,
890 struct device_node *remove_ce_node)
891 {
892 struct overlay_changeset *ovcs;
893 struct of_changeset_entry *ce;
894
895 list_for_each_entry_reverse(ovcs, &ovcs_list, ovcs_list) {
896 if (ovcs == remove_ovcs)
897 break;
898
899 list_for_each_entry(ce, &ovcs->cset.entries, node) {
900 if (find_node(ce->np, remove_ce_node)) {
901 pr_err("%s: #%d overlaps with #%d @%pOF\n",
902 __func__, remove_ovcs->id, ovcs->id,
903 remove_ce_node);
904 return 1;
905 }
906 if (find_node(remove_ce_node, ce->np)) {
907 pr_err("%s: #%d overlaps with #%d @%pOF\n",
908 __func__, remove_ovcs->id, ovcs->id,
909 remove_ce_node);
910 return 1;
911 }
912 }
913 }
914
915 return 0;
916 }
917
918 /*
919 * We can safely remove the overlay only if it's the top-most one.
920 * Newly applied overlays are inserted at the tail of the overlay list,
921 * so a top most overlay is the one that is closest to the tail.
922 *
923 * The topmost check is done by exploiting this property. For each
924 * affected device node in the log list we check if this overlay is
925 * the one closest to the tail. If another overlay has affected this
926 * device node and is closest to the tail, then removal is not permited.
927 */
928 static int overlay_removal_is_ok(struct overlay_changeset *remove_ovcs)
929 {
930 struct of_changeset_entry *remove_ce;
931
932 list_for_each_entry(remove_ce, &remove_ovcs->cset.entries, node) {
933 if (node_overlaps_later_cs(remove_ovcs, remove_ce->np)) {
934 pr_err("overlay #%d is not topmost\n", remove_ovcs->id);
935 return 0;
936 }
937 }
938
939 return 1;
940 }
941
942 /**
943 * of_overlay_remove() - Revert and free an overlay changeset
944 * @ovcs_id: Pointer to overlay changeset id
945 *
946 * Removes an overlay if it is permissible. @ovcs_id was previously returned
947 * by of_overlay_apply().
948 *
949 * If an error occurred while attempting to revert the overlay changeset,
950 * then an attempt is made to re-apply any changeset entry that was
951 * reverted. If an error occurs on re-apply then the state of the device
952 * tree can not be determined, and any following attempt to apply or remove
953 * an overlay changeset will be refused.
954 *
955 * A non-zero return value will not revert the changeset if error is from:
956 * - parameter checks
957 * - overlay changeset pre-remove notifier
958 * - overlay changeset entry revert
959 *
960 * If an error is returned by an overlay changeset pre-remove notifier
961 * then no further overlay changeset pre-remove notifier will be called.
962 *
963 * If more than one notifier returns an error, then the last notifier
964 * error to occur is returned.
965 *
966 * A non-zero return value will revert the changeset if error is from:
967 * - overlay changeset entry notifier
968 * - overlay changeset post-remove notifier
969 *
970 * If an error is returned by an overlay changeset post-remove notifier
971 * then no further overlay changeset post-remove notifier will be called.
972 *
973 * Returns 0 on success, or a negative error number. *ovcs_id is set to
974 * zero after reverting the changeset, even if a subsequent error occurs.
975 */
976 int of_overlay_remove(int *ovcs_id)
977 {
978 struct overlay_changeset *ovcs;
979 int ret, ret_apply, ret_tmp;
980
981 ret = 0;
982
983 if (devicetree_corrupt()) {
984 pr_err("suspect devicetree state, refuse to remove overlay\n");
985 ret = -EBUSY;
986 goto out;
987 }
988
989 mutex_lock(&of_mutex);
990
991 ovcs = idr_find(&ovcs_idr, *ovcs_id);
992 if (!ovcs) {
993 ret = -ENODEV;
994 pr_err("remove: Could not find overlay #%d\n", *ovcs_id);
995 goto out_unlock;
996 }
997
998 if (!overlay_removal_is_ok(ovcs)) {
999 ret = -EBUSY;
1000 goto out_unlock;
1001 }
1002
1003 ret = overlay_notify(ovcs, OF_OVERLAY_PRE_REMOVE);
1004 if (ret) {
1005 pr_err("overlay changeset pre-remove notify error %d\n", ret);
1006 goto out_unlock;
1007 }
1008
1009 list_del(&ovcs->ovcs_list);
1010
1011 ret_apply = 0;
1012 ret = __of_changeset_revert_entries(&ovcs->cset, &ret_apply);
1013 if (ret) {
1014 if (ret_apply)
1015 devicetree_state_flags |= DTSF_REVERT_FAIL;
1016 goto out_unlock;
1017 }
1018
1019 ret = __of_changeset_revert_notify(&ovcs->cset);
1020 if (ret)
1021 pr_err("overlay changeset entry notify error %d\n", ret);
1022 /* notify failure is not fatal, continue */
1023
1024 *ovcs_id = 0;
1025
1026 ret_tmp = overlay_notify(ovcs, OF_OVERLAY_POST_REMOVE);
1027 if (ret_tmp) {
1028 pr_err("overlay changeset post-remove notify error %d\n",
1029 ret_tmp);
1030 if (!ret)
1031 ret = ret_tmp;
1032 }
1033
1034 free_overlay_changeset(ovcs);
1035
1036 out_unlock:
1037 mutex_unlock(&of_mutex);
1038
1039 out:
1040 pr_debug("%s() err=%d\n", __func__, ret);
1041
1042 return ret;
1043 }
1044 EXPORT_SYMBOL_GPL(of_overlay_remove);
1045
1046 /**
1047 * of_overlay_remove_all() - Reverts and frees all overlay changesets
1048 *
1049 * Removes all overlays from the system in the correct order.
1050 *
1051 * Returns 0 on success, or a negative error number
1052 */
1053 int of_overlay_remove_all(void)
1054 {
1055 struct overlay_changeset *ovcs, *ovcs_n;
1056 int ret;
1057
1058 /* the tail of list is guaranteed to be safe to remove */
1059 list_for_each_entry_safe_reverse(ovcs, ovcs_n, &ovcs_list, ovcs_list) {
1060 ret = of_overlay_remove(&ovcs->id);
1061 if (ret)
1062 return ret;
1063 }
1064
1065 return 0;
1066 }
1067 EXPORT_SYMBOL_GPL(of_overlay_remove_all);