xref: /openbmc/linux/drivers/of/overlay.c (revision c819e2cf)
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 #undef DEBUG
12 #include <linux/kernel.h>
13 #include <linux/module.h>
14 #include <linux/of.h>
15 #include <linux/of_device.h>
16 #include <linux/string.h>
17 #include <linux/ctype.h>
18 #include <linux/errno.h>
19 #include <linux/string.h>
20 #include <linux/slab.h>
21 #include <linux/err.h>
22 
23 #include "of_private.h"
24 
25 /**
26  * struct of_overlay_info - Holds a single overlay info
27  * @target:	target of the overlay operation
28  * @overlay:	pointer to the overlay contents node
29  *
30  * Holds a single overlay state, including all the overlay logs &
31  * records.
32  */
33 struct of_overlay_info {
34 	struct device_node *target;
35 	struct device_node *overlay;
36 };
37 
38 /**
39  * struct of_overlay - Holds a complete overlay transaction
40  * @node:	List on which we are located
41  * @count:	Count of ovinfo structures
42  * @ovinfo_tab:	Overlay info table (count sized)
43  * @cset:	Changeset to be used
44  *
45  * Holds a complete overlay transaction
46  */
47 struct of_overlay {
48 	int id;
49 	struct list_head node;
50 	int count;
51 	struct of_overlay_info *ovinfo_tab;
52 	struct of_changeset cset;
53 };
54 
55 static int of_overlay_apply_one(struct of_overlay *ov,
56 		struct device_node *target, const struct device_node *overlay);
57 
58 static int of_overlay_apply_single_property(struct of_overlay *ov,
59 		struct device_node *target, struct property *prop)
60 {
61 	struct property *propn, *tprop;
62 
63 	/* NOTE: Multiple changes of single properties not supported */
64 	tprop = of_find_property(target, prop->name, NULL);
65 
66 	/* special properties are not meant to be updated (silent NOP) */
67 	if (of_prop_cmp(prop->name, "name") == 0 ||
68 	    of_prop_cmp(prop->name, "phandle") == 0 ||
69 	    of_prop_cmp(prop->name, "linux,phandle") == 0)
70 		return 0;
71 
72 	propn = __of_prop_dup(prop, GFP_KERNEL);
73 	if (propn == NULL)
74 		return -ENOMEM;
75 
76 	/* not found? add */
77 	if (tprop == NULL)
78 		return of_changeset_add_property(&ov->cset, target, propn);
79 
80 	/* found? update */
81 	return of_changeset_update_property(&ov->cset, target, propn);
82 }
83 
84 static int of_overlay_apply_single_device_node(struct of_overlay *ov,
85 		struct device_node *target, struct device_node *child)
86 {
87 	const char *cname;
88 	struct device_node *tchild, *grandchild;
89 	int ret = 0;
90 
91 	cname = kbasename(child->full_name);
92 	if (cname == NULL)
93 		return -ENOMEM;
94 
95 	/* NOTE: Multiple mods of created nodes not supported */
96 	tchild = of_get_child_by_name(target, cname);
97 	if (tchild != NULL) {
98 		/* apply overlay recursively */
99 		ret = of_overlay_apply_one(ov, tchild, child);
100 		of_node_put(tchild);
101 	} else {
102 		/* create empty tree as a target */
103 		tchild = __of_node_dup(child, "%s/%s", target->full_name, cname);
104 		if (!tchild)
105 			return -ENOMEM;
106 
107 		/* point to parent */
108 		tchild->parent = target;
109 
110 		ret = of_changeset_attach_node(&ov->cset, tchild);
111 		if (ret)
112 			return ret;
113 
114 		ret = of_overlay_apply_one(ov, tchild, child);
115 		if (ret)
116 			return ret;
117 	}
118 
119 	return ret;
120 }
121 
122 /*
123  * Apply a single overlay node recursively.
124  *
125  * Note that the in case of an error the target node is left
126  * in a inconsistent state. Error recovery should be performed
127  * by using the changeset.
128  */
129 static int of_overlay_apply_one(struct of_overlay *ov,
130 		struct device_node *target, const struct device_node *overlay)
131 {
132 	struct device_node *child;
133 	struct property *prop;
134 	int ret;
135 
136 	for_each_property_of_node(overlay, prop) {
137 		ret = of_overlay_apply_single_property(ov, target, prop);
138 		if (ret) {
139 			pr_err("%s: Failed to apply prop @%s/%s\n",
140 				__func__, target->full_name, prop->name);
141 			return ret;
142 		}
143 	}
144 
145 	for_each_child_of_node(overlay, child) {
146 		ret = of_overlay_apply_single_device_node(ov, target, child);
147 		if (ret != 0) {
148 			pr_err("%s: Failed to apply single node @%s/%s\n",
149 					__func__, target->full_name,
150 					child->name);
151 			return ret;
152 		}
153 	}
154 
155 	return 0;
156 }
157 
158 /**
159  * of_overlay_apply() - Apply @count overlays pointed at by @ovinfo_tab
160  * @ov:		Overlay to apply
161  *
162  * Applies the overlays given, while handling all error conditions
163  * appropriately. Either the operation succeeds, or if it fails the
164  * live tree is reverted to the state before the attempt.
165  * Returns 0, or an error if the overlay attempt failed.
166  */
167 static int of_overlay_apply(struct of_overlay *ov)
168 {
169 	int i, err;
170 
171 	/* first we apply the overlays atomically */
172 	for (i = 0; i < ov->count; i++) {
173 		struct of_overlay_info *ovinfo = &ov->ovinfo_tab[i];
174 
175 		err = of_overlay_apply_one(ov, ovinfo->target, ovinfo->overlay);
176 		if (err != 0) {
177 			pr_err("%s: overlay failed '%s'\n",
178 				__func__, ovinfo->target->full_name);
179 			return err;
180 		}
181 	}
182 
183 	return 0;
184 }
185 
186 /*
187  * Find the target node using a number of different strategies
188  * in order of preference
189  *
190  * "target" property containing the phandle of the target
191  * "target-path" property containing the path of the target
192  */
193 static struct device_node *find_target_node(struct device_node *info_node)
194 {
195 	const char *path;
196 	u32 val;
197 	int ret;
198 
199 	/* first try to go by using the target as a phandle */
200 	ret = of_property_read_u32(info_node, "target", &val);
201 	if (ret == 0)
202 		return of_find_node_by_phandle(val);
203 
204 	/* now try to locate by path */
205 	ret = of_property_read_string(info_node, "target-path", &path);
206 	if (ret == 0)
207 		return of_find_node_by_path(path);
208 
209 	pr_err("%s: Failed to find target for node %p (%s)\n", __func__,
210 		info_node, info_node->name);
211 
212 	return NULL;
213 }
214 
215 /**
216  * of_fill_overlay_info() - Fill an overlay info structure
217  * @ov		Overlay to fill
218  * @info_node:	Device node containing the overlay
219  * @ovinfo:	Pointer to the overlay info structure to fill
220  *
221  * Fills an overlay info structure with the overlay information
222  * from a device node. This device node must have a target property
223  * which contains a phandle of the overlay target node, and an
224  * __overlay__ child node which has the overlay contents.
225  * Both ovinfo->target & ovinfo->overlay have their references taken.
226  *
227  * Returns 0 on success, or a negative error value.
228  */
229 static int of_fill_overlay_info(struct of_overlay *ov,
230 		struct device_node *info_node, struct of_overlay_info *ovinfo)
231 {
232 	ovinfo->overlay = of_get_child_by_name(info_node, "__overlay__");
233 	if (ovinfo->overlay == NULL)
234 		goto err_fail;
235 
236 	ovinfo->target = find_target_node(info_node);
237 	if (ovinfo->target == NULL)
238 		goto err_fail;
239 
240 	return 0;
241 
242 err_fail:
243 	of_node_put(ovinfo->target);
244 	of_node_put(ovinfo->overlay);
245 
246 	memset(ovinfo, 0, sizeof(*ovinfo));
247 	return -EINVAL;
248 }
249 
250 /**
251  * of_build_overlay_info() - Build an overlay info array
252  * @ov		Overlay to build
253  * @tree:	Device node containing all the overlays
254  *
255  * Helper function that given a tree containing overlay information,
256  * allocates and builds an overlay info array containing it, ready
257  * for use using of_overlay_apply.
258  *
259  * Returns 0 on success with the @cntp @ovinfop pointers valid,
260  * while on error a negative error value is returned.
261  */
262 static int of_build_overlay_info(struct of_overlay *ov,
263 		struct device_node *tree)
264 {
265 	struct device_node *node;
266 	struct of_overlay_info *ovinfo;
267 	int cnt, err;
268 
269 	/* worst case; every child is a node */
270 	cnt = 0;
271 	for_each_child_of_node(tree, node)
272 		cnt++;
273 
274 	ovinfo = kcalloc(cnt, sizeof(*ovinfo), GFP_KERNEL);
275 	if (ovinfo == NULL)
276 		return -ENOMEM;
277 
278 	cnt = 0;
279 	for_each_child_of_node(tree, node) {
280 		memset(&ovinfo[cnt], 0, sizeof(*ovinfo));
281 		err = of_fill_overlay_info(ov, node, &ovinfo[cnt]);
282 		if (err == 0)
283 			cnt++;
284 	}
285 
286 	/* if nothing filled, return error */
287 	if (cnt == 0) {
288 		kfree(ovinfo);
289 		return -ENODEV;
290 	}
291 
292 	ov->count = cnt;
293 	ov->ovinfo_tab = ovinfo;
294 
295 	return 0;
296 }
297 
298 /**
299  * of_free_overlay_info() - Free an overlay info array
300  * @ov		Overlay to free the overlay info from
301  * @ovinfo_tab:	Array of overlay_info's to free
302  *
303  * Releases the memory of a previously allocated ovinfo array
304  * by of_build_overlay_info.
305  * Returns 0, or an error if the arguments are bogus.
306  */
307 static int of_free_overlay_info(struct of_overlay *ov)
308 {
309 	struct of_overlay_info *ovinfo;
310 	int i;
311 
312 	/* do it in reverse */
313 	for (i = ov->count - 1; i >= 0; i--) {
314 		ovinfo = &ov->ovinfo_tab[i];
315 
316 		of_node_put(ovinfo->target);
317 		of_node_put(ovinfo->overlay);
318 	}
319 	kfree(ov->ovinfo_tab);
320 
321 	return 0;
322 }
323 
324 static LIST_HEAD(ov_list);
325 static DEFINE_IDR(ov_idr);
326 
327 /**
328  * of_overlay_create() - Create and apply an overlay
329  * @tree:	Device node containing all the overlays
330  *
331  * Creates and applies an overlay while also keeping track
332  * of the overlay in a list. This list can be used to prevent
333  * illegal overlay removals.
334  *
335  * Returns the id of the created overlay, or an negative error number
336  */
337 int of_overlay_create(struct device_node *tree)
338 {
339 	struct of_overlay *ov;
340 	int err, id;
341 
342 	/* allocate the overlay structure */
343 	ov = kzalloc(sizeof(*ov), GFP_KERNEL);
344 	if (ov == NULL)
345 		return -ENOMEM;
346 	ov->id = -1;
347 
348 	INIT_LIST_HEAD(&ov->node);
349 
350 	of_changeset_init(&ov->cset);
351 
352 	mutex_lock(&of_mutex);
353 
354 	id = idr_alloc(&ov_idr, ov, 0, 0, GFP_KERNEL);
355 	if (id < 0) {
356 		pr_err("%s: idr_alloc() failed for tree@%s\n",
357 				__func__, tree->full_name);
358 		err = id;
359 		goto err_destroy_trans;
360 	}
361 	ov->id = id;
362 
363 	/* build the overlay info structures */
364 	err = of_build_overlay_info(ov, tree);
365 	if (err) {
366 		pr_err("%s: of_build_overlay_info() failed for tree@%s\n",
367 				__func__, tree->full_name);
368 		goto err_free_idr;
369 	}
370 
371 	/* apply the overlay */
372 	err = of_overlay_apply(ov);
373 	if (err) {
374 		pr_err("%s: of_overlay_apply() failed for tree@%s\n",
375 				__func__, tree->full_name);
376 		goto err_abort_trans;
377 	}
378 
379 	/* apply the changeset */
380 	err = of_changeset_apply(&ov->cset);
381 	if (err) {
382 		pr_err("%s: of_changeset_apply() failed for tree@%s\n",
383 				__func__, tree->full_name);
384 		goto err_revert_overlay;
385 	}
386 
387 	/* add to the tail of the overlay list */
388 	list_add_tail(&ov->node, &ov_list);
389 
390 	mutex_unlock(&of_mutex);
391 
392 	return id;
393 
394 err_revert_overlay:
395 err_abort_trans:
396 	of_free_overlay_info(ov);
397 err_free_idr:
398 	idr_remove(&ov_idr, ov->id);
399 err_destroy_trans:
400 	of_changeset_destroy(&ov->cset);
401 	kfree(ov);
402 	mutex_unlock(&of_mutex);
403 
404 	return err;
405 }
406 EXPORT_SYMBOL_GPL(of_overlay_create);
407 
408 /* check whether the given node, lies under the given tree */
409 static int overlay_subtree_check(struct device_node *tree,
410 		struct device_node *dn)
411 {
412 	struct device_node *child;
413 
414 	/* match? */
415 	if (tree == dn)
416 		return 1;
417 
418 	for_each_child_of_node(tree, child) {
419 		if (overlay_subtree_check(child, dn))
420 			return 1;
421 	}
422 
423 	return 0;
424 }
425 
426 /* check whether this overlay is the topmost */
427 static int overlay_is_topmost(struct of_overlay *ov, struct device_node *dn)
428 {
429 	struct of_overlay *ovt;
430 	struct of_changeset_entry *ce;
431 
432 	list_for_each_entry_reverse(ovt, &ov_list, node) {
433 		/* if we hit ourselves, we're done */
434 		if (ovt == ov)
435 			break;
436 
437 		/* check against each subtree affected by this overlay */
438 		list_for_each_entry(ce, &ovt->cset.entries, node) {
439 			if (overlay_subtree_check(ce->np, dn)) {
440 				pr_err("%s: #%d clashes #%d @%s\n",
441 					__func__, ov->id, ovt->id,
442 					dn->full_name);
443 				return 0;
444 			}
445 		}
446 	}
447 
448 	/* overlay is topmost */
449 	return 1;
450 }
451 
452 /*
453  * We can safely remove the overlay only if it's the top-most one.
454  * Newly applied overlays are inserted at the tail of the overlay list,
455  * so a top most overlay is the one that is closest to the tail.
456  *
457  * The topmost check is done by exploiting this property. For each
458  * affected device node in the log list we check if this overlay is
459  * the one closest to the tail. If another overlay has affected this
460  * device node and is closest to the tail, then removal is not permited.
461  */
462 static int overlay_removal_is_ok(struct of_overlay *ov)
463 {
464 	struct of_changeset_entry *ce;
465 
466 	list_for_each_entry(ce, &ov->cset.entries, node) {
467 		if (!overlay_is_topmost(ov, ce->np)) {
468 			pr_err("%s: overlay #%d is not topmost\n",
469 					__func__, ov->id);
470 			return 0;
471 		}
472 	}
473 
474 	return 1;
475 }
476 
477 /**
478  * of_overlay_destroy() - Removes an overlay
479  * @id:	Overlay id number returned by a previous call to of_overlay_create
480  *
481  * Removes an overlay if it is permissible.
482  *
483  * Returns 0 on success, or an negative error number
484  */
485 int of_overlay_destroy(int id)
486 {
487 	struct of_overlay *ov;
488 	int err;
489 
490 	mutex_lock(&of_mutex);
491 
492 	ov = idr_find(&ov_idr, id);
493 	if (ov == NULL) {
494 		err = -ENODEV;
495 		pr_err("%s: Could not find overlay #%d\n",
496 				__func__, id);
497 		goto out;
498 	}
499 
500 	/* check whether the overlay is safe to remove */
501 	if (!overlay_removal_is_ok(ov)) {
502 		err = -EBUSY;
503 		pr_err("%s: removal check failed for overlay #%d\n",
504 				__func__, id);
505 		goto out;
506 	}
507 
508 
509 	list_del(&ov->node);
510 	of_changeset_revert(&ov->cset);
511 	of_free_overlay_info(ov);
512 	idr_remove(&ov_idr, id);
513 	of_changeset_destroy(&ov->cset);
514 	kfree(ov);
515 
516 	err = 0;
517 
518 out:
519 	mutex_unlock(&of_mutex);
520 
521 	return err;
522 }
523 EXPORT_SYMBOL_GPL(of_overlay_destroy);
524 
525 /**
526  * of_overlay_destroy_all() - Removes all overlays from the system
527  *
528  * Removes all overlays from the system in the correct order.
529  *
530  * Returns 0 on success, or an negative error number
531  */
532 int of_overlay_destroy_all(void)
533 {
534 	struct of_overlay *ov, *ovn;
535 
536 	mutex_lock(&of_mutex);
537 
538 	/* the tail of list is guaranteed to be safe to remove */
539 	list_for_each_entry_safe_reverse(ov, ovn, &ov_list, node) {
540 		list_del(&ov->node);
541 		of_changeset_revert(&ov->cset);
542 		of_free_overlay_info(ov);
543 		idr_remove(&ov_idr, ov->id);
544 		kfree(ov);
545 	}
546 
547 	mutex_unlock(&of_mutex);
548 
549 	return 0;
550 }
551 EXPORT_SYMBOL_GPL(of_overlay_destroy_all);
552