Linux Audio

Check our new training course

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