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