1075 lines · c
1// SPDX-License-Identifier: GPL-2.02/*3 * Support for dynamic device trees.4 *5 * On some platforms, the device tree can be manipulated at runtime.6 * The routines in this section support adding, removing and changing7 * device tree nodes.8 */9 10#define pr_fmt(fmt) "OF: " fmt11 12#include <linux/cleanup.h>13#include <linux/device.h>14#include <linux/of.h>15#include <linux/spinlock.h>16#include <linux/slab.h>17#include <linux/string.h>18#include <linux/proc_fs.h>19 20#include "of_private.h"21 22static struct device_node *kobj_to_device_node(struct kobject *kobj)23{24 return container_of(kobj, struct device_node, kobj);25}26 27/**28 * of_node_get() - Increment refcount of a node29 * @node: Node to inc refcount, NULL is supported to simplify writing of30 * callers31 *32 * Return: The node with refcount incremented.33 */34struct device_node *of_node_get(struct device_node *node)35{36 if (node)37 kobject_get(&node->kobj);38 return node;39}40EXPORT_SYMBOL(of_node_get);41 42/**43 * of_node_put() - Decrement refcount of a node44 * @node: Node to dec refcount, NULL is supported to simplify writing of45 * callers46 */47void of_node_put(struct device_node *node)48{49 if (node)50 kobject_put(&node->kobj);51}52EXPORT_SYMBOL(of_node_put);53 54static BLOCKING_NOTIFIER_HEAD(of_reconfig_chain);55 56int of_reconfig_notifier_register(struct notifier_block *nb)57{58 return blocking_notifier_chain_register(&of_reconfig_chain, nb);59}60EXPORT_SYMBOL_GPL(of_reconfig_notifier_register);61 62int of_reconfig_notifier_unregister(struct notifier_block *nb)63{64 return blocking_notifier_chain_unregister(&of_reconfig_chain, nb);65}66EXPORT_SYMBOL_GPL(of_reconfig_notifier_unregister);67 68static const char *action_names[] = {69 [0] = "INVALID",70 [OF_RECONFIG_ATTACH_NODE] = "ATTACH_NODE",71 [OF_RECONFIG_DETACH_NODE] = "DETACH_NODE",72 [OF_RECONFIG_ADD_PROPERTY] = "ADD_PROPERTY",73 [OF_RECONFIG_REMOVE_PROPERTY] = "REMOVE_PROPERTY",74 [OF_RECONFIG_UPDATE_PROPERTY] = "UPDATE_PROPERTY",75};76 77#define _do_print(func, prefix, action, node, prop, ...) ({ \78 func("changeset: " prefix "%-15s %pOF%s%s\n", \79 ##__VA_ARGS__, action_names[action], node, \80 prop ? ":" : "", prop ? prop->name : ""); \81})82#define of_changeset_action_err(...) _do_print(pr_err, __VA_ARGS__)83#define of_changeset_action_debug(...) _do_print(pr_debug, __VA_ARGS__)84 85int of_reconfig_notify(unsigned long action, struct of_reconfig_data *p)86{87 int rc;88 struct of_reconfig_data *pr = p;89 90 of_changeset_action_debug("notify: ", action, pr->dn, pr->prop);91 92 rc = blocking_notifier_call_chain(&of_reconfig_chain, action, p);93 return notifier_to_errno(rc);94}95 96/*97 * of_reconfig_get_state_change() - Returns new state of device98 * @action - action of the of notifier99 * @arg - argument of the of notifier100 *101 * Returns the new state of a device based on the notifier used.102 *103 * Return: OF_RECONFIG_CHANGE_REMOVE on device going from enabled to104 * disabled, OF_RECONFIG_CHANGE_ADD on device going from disabled to105 * enabled and OF_RECONFIG_NO_CHANGE on no change.106 */107int of_reconfig_get_state_change(unsigned long action, struct of_reconfig_data *pr)108{109 struct property *prop, *old_prop = NULL;110 int is_status, status_state, old_status_state, prev_state, new_state;111 112 /* figure out if a device should be created or destroyed */113 switch (action) {114 case OF_RECONFIG_ATTACH_NODE:115 case OF_RECONFIG_DETACH_NODE:116 prop = of_find_property(pr->dn, "status", NULL);117 break;118 case OF_RECONFIG_ADD_PROPERTY:119 case OF_RECONFIG_REMOVE_PROPERTY:120 prop = pr->prop;121 break;122 case OF_RECONFIG_UPDATE_PROPERTY:123 prop = pr->prop;124 old_prop = pr->old_prop;125 break;126 default:127 return OF_RECONFIG_NO_CHANGE;128 }129 130 is_status = 0;131 status_state = -1;132 old_status_state = -1;133 prev_state = -1;134 new_state = -1;135 136 if (prop && !strcmp(prop->name, "status")) {137 is_status = 1;138 status_state = !strcmp(prop->value, "okay") ||139 !strcmp(prop->value, "ok");140 if (old_prop)141 old_status_state = !strcmp(old_prop->value, "okay") ||142 !strcmp(old_prop->value, "ok");143 }144 145 switch (action) {146 case OF_RECONFIG_ATTACH_NODE:147 prev_state = 0;148 /* -1 & 0 status either missing or okay */149 new_state = status_state != 0;150 break;151 case OF_RECONFIG_DETACH_NODE:152 /* -1 & 0 status either missing or okay */153 prev_state = status_state != 0;154 new_state = 0;155 break;156 case OF_RECONFIG_ADD_PROPERTY:157 if (is_status) {158 /* no status property -> enabled (legacy) */159 prev_state = 1;160 new_state = status_state;161 }162 break;163 case OF_RECONFIG_REMOVE_PROPERTY:164 if (is_status) {165 prev_state = status_state;166 /* no status property -> enabled (legacy) */167 new_state = 1;168 }169 break;170 case OF_RECONFIG_UPDATE_PROPERTY:171 if (is_status) {172 prev_state = old_status_state != 0;173 new_state = status_state != 0;174 }175 break;176 }177 178 if (prev_state == new_state)179 return OF_RECONFIG_NO_CHANGE;180 181 return new_state ? OF_RECONFIG_CHANGE_ADD : OF_RECONFIG_CHANGE_REMOVE;182}183EXPORT_SYMBOL_GPL(of_reconfig_get_state_change);184 185int of_property_notify(int action, struct device_node *np,186 struct property *prop, struct property *oldprop)187{188 struct of_reconfig_data pr;189 190 /* only call notifiers if the node is attached */191 if (!of_node_is_attached(np))192 return 0;193 194 pr.dn = np;195 pr.prop = prop;196 pr.old_prop = oldprop;197 return of_reconfig_notify(action, &pr);198}199 200static void __of_attach_node(struct device_node *np)201{202 const __be32 *phandle;203 int sz;204 unsigned long flags;205 206 raw_spin_lock_irqsave(&devtree_lock, flags);207 208 if (!of_node_check_flag(np, OF_OVERLAY)) {209 np->name = __of_get_property(np, "name", NULL);210 if (!np->name)211 np->name = "<NULL>";212 213 phandle = __of_get_property(np, "phandle", &sz);214 if (!phandle)215 phandle = __of_get_property(np, "linux,phandle", &sz);216 if (IS_ENABLED(CONFIG_PPC_PSERIES) && !phandle)217 phandle = __of_get_property(np, "ibm,phandle", &sz);218 if (phandle && (sz >= 4))219 np->phandle = be32_to_cpup(phandle);220 else221 np->phandle = 0;222 }223 224 np->child = NULL;225 np->sibling = np->parent->child;226 np->parent->child = np;227 of_node_clear_flag(np, OF_DETACHED);228 np->fwnode.flags |= FWNODE_FLAG_NOT_DEVICE;229 230 raw_spin_unlock_irqrestore(&devtree_lock, flags);231 232 __of_attach_node_sysfs(np);233}234 235/**236 * of_attach_node() - Plug a device node into the tree and global list.237 * @np: Pointer to the caller's Device Node238 */239int of_attach_node(struct device_node *np)240{241 struct of_reconfig_data rd;242 243 memset(&rd, 0, sizeof(rd));244 rd.dn = np;245 246 mutex_lock(&of_mutex);247 __of_attach_node(np);248 mutex_unlock(&of_mutex);249 250 of_reconfig_notify(OF_RECONFIG_ATTACH_NODE, &rd);251 252 return 0;253}254 255void __of_detach_node(struct device_node *np)256{257 struct device_node *parent;258 unsigned long flags;259 260 raw_spin_lock_irqsave(&devtree_lock, flags);261 262 parent = np->parent;263 if (WARN_ON(of_node_check_flag(np, OF_DETACHED) || !parent)) {264 raw_spin_unlock_irqrestore(&devtree_lock, flags);265 return;266 }267 268 if (parent->child == np)269 parent->child = np->sibling;270 else {271 struct device_node *prevsib;272 for (prevsib = np->parent->child;273 prevsib->sibling != np;274 prevsib = prevsib->sibling)275 ;276 prevsib->sibling = np->sibling;277 }278 279 of_node_set_flag(np, OF_DETACHED);280 281 /* race with of_find_node_by_phandle() prevented by devtree_lock */282 __of_phandle_cache_inv_entry(np->phandle);283 284 raw_spin_unlock_irqrestore(&devtree_lock, flags);285 286 __of_detach_node_sysfs(np);287}288 289/**290 * of_detach_node() - "Unplug" a node from the device tree.291 * @np: Pointer to the caller's Device Node292 */293int of_detach_node(struct device_node *np)294{295 struct of_reconfig_data rd;296 297 memset(&rd, 0, sizeof(rd));298 rd.dn = np;299 300 mutex_lock(&of_mutex);301 __of_detach_node(np);302 mutex_unlock(&of_mutex);303 304 of_reconfig_notify(OF_RECONFIG_DETACH_NODE, &rd);305 306 return 0;307}308EXPORT_SYMBOL_GPL(of_detach_node);309 310void __of_prop_free(struct property *prop)311{312 kfree(prop->name);313 kfree(prop->value);314 kfree(prop);315}316 317static void property_list_free(struct property *prop_list)318{319 struct property *prop, *next;320 321 for (prop = prop_list; prop != NULL; prop = next) {322 next = prop->next;323 __of_prop_free(prop);324 }325}326 327/**328 * of_node_release() - release a dynamically allocated node329 * @kobj: kernel object of the node to be released330 *331 * In of_node_put() this function is passed to kref_put() as the destructor.332 */333void of_node_release(struct kobject *kobj)334{335 struct device_node *node = kobj_to_device_node(kobj);336 337 /*338 * can not use '"%pOF", node' in pr_err() calls from this function339 * because an of_node_get(node) when refcount is already zero340 * will result in an error and a stack dump341 */342 343 /* We should never be releasing nodes that haven't been detached. */344 if (!of_node_check_flag(node, OF_DETACHED)) {345 346 pr_err("ERROR: %s() detected bad of_node_put() on %pOF/%s\n",347 __func__, node->parent, node->full_name);348 349 /*350 * of unittests will test this path. Do not print the stack351 * trace when the error is caused by unittest so that we do352 * not display what a normal developer might reasonably353 * consider a real bug.354 */355 if (!IS_ENABLED(CONFIG_OF_UNITTEST) ||356 strcmp(node->parent->full_name, "testcase-data")) {357 dump_stack();358 pr_err("ERROR: next of_node_put() on this node will result in a kobject warning 'refcount_t: underflow; use-after-free.'\n");359 }360 361 return;362 }363 if (!of_node_check_flag(node, OF_DYNAMIC))364 return;365 366 if (of_node_check_flag(node, OF_OVERLAY)) {367 368 if (!of_node_check_flag(node, OF_OVERLAY_FREE_CSET)) {369 /* premature refcount of zero, do not free memory */370 pr_err("ERROR: memory leak before free overlay changeset, %pOF\n",371 node);372 return;373 }374 375 /*376 * If node->properties non-empty then properties were added377 * to this node either by different overlay that has not378 * yet been removed, or by a non-overlay mechanism.379 */380 if (node->properties)381 pr_err("ERROR: %s(), unexpected properties in %pOF\n",382 __func__, node);383 }384 385 if (node->child)386 pr_err("ERROR: %s() unexpected children for %pOF/%s\n",387 __func__, node->parent, node->full_name);388 389 property_list_free(node->properties);390 property_list_free(node->deadprops);391 fwnode_links_purge(of_fwnode_handle(node));392 393 kfree(node->full_name);394 kfree(node->data);395 kfree(node);396}397 398/**399 * __of_prop_dup - Copy a property dynamically.400 * @prop: Property to copy401 * @allocflags: Allocation flags (typically pass GFP_KERNEL)402 *403 * Copy a property by dynamically allocating the memory of both the404 * property structure and the property name & contents. The property's405 * flags have the OF_DYNAMIC bit set so that we can differentiate between406 * dynamically allocated properties and not.407 *408 * Return: The newly allocated property or NULL on out of memory error.409 */410struct property *__of_prop_dup(const struct property *prop, gfp_t allocflags)411{412 struct property *new;413 414 new = kzalloc(sizeof(*new), allocflags);415 if (!new)416 return NULL;417 418 /*419 * NOTE: There is no check for zero length value.420 * In case of a boolean property, this will allocate a value421 * of zero bytes. We do this to work around the use422 * of of_get_property() calls on boolean values.423 */424 new->name = kstrdup(prop->name, allocflags);425 new->value = kmemdup(prop->value, prop->length, allocflags);426 new->length = prop->length;427 if (!new->name || !new->value)428 goto err_free;429 430 /* mark the property as dynamic */431 of_property_set_flag(new, OF_DYNAMIC);432 433 return new;434 435 err_free:436 __of_prop_free(new);437 return NULL;438}439 440/**441 * __of_node_dup() - Duplicate or create an empty device node dynamically.442 * @np: if not NULL, contains properties to be duplicated in new node443 * @full_name: string value to be duplicated into new node's full_name field444 *445 * Create a device tree node, optionally duplicating the properties of446 * another node. The node data are dynamically allocated and all the node447 * flags have the OF_DYNAMIC & OF_DETACHED bits set.448 *449 * Return: The newly allocated node or NULL on out of memory error. Use450 * of_node_put() on it when done to free the memory allocated for it.451 */452struct device_node *__of_node_dup(const struct device_node *np,453 const char *full_name)454{455 struct device_node *node;456 457 node = kzalloc(sizeof(*node), GFP_KERNEL);458 if (!node)459 return NULL;460 node->full_name = kstrdup(full_name, GFP_KERNEL);461 if (!node->full_name) {462 kfree(node);463 return NULL;464 }465 466 of_node_set_flag(node, OF_DYNAMIC);467 of_node_set_flag(node, OF_DETACHED);468 of_node_init(node);469 470 /* Iterate over and duplicate all properties */471 if (np) {472 struct property *pp, *new_pp;473 for_each_property_of_node(np, pp) {474 new_pp = __of_prop_dup(pp, GFP_KERNEL);475 if (!new_pp)476 goto err_prop;477 if (__of_add_property(node, new_pp)) {478 __of_prop_free(new_pp);479 goto err_prop;480 }481 }482 }483 return node;484 485 err_prop:486 of_node_put(node); /* Frees the node and properties */487 return NULL;488}489 490/**491 * of_changeset_create_node - Dynamically create a device node and attach to492 * a given changeset.493 *494 * @ocs: Pointer to changeset495 * @parent: Pointer to parent device node496 * @full_name: Node full name497 *498 * Return: Pointer to the created device node or NULL in case of an error.499 */500struct device_node *of_changeset_create_node(struct of_changeset *ocs,501 struct device_node *parent,502 const char *full_name)503{504 struct device_node *np;505 int ret;506 507 np = __of_node_dup(NULL, full_name);508 if (!np)509 return NULL;510 np->parent = parent;511 512 ret = of_changeset_attach_node(ocs, np);513 if (ret) {514 of_node_put(np);515 return NULL;516 }517 518 return np;519}520EXPORT_SYMBOL(of_changeset_create_node);521 522static void __of_changeset_entry_destroy(struct of_changeset_entry *ce)523{524 if (ce->action == OF_RECONFIG_ATTACH_NODE &&525 of_node_check_flag(ce->np, OF_OVERLAY)) {526 if (kref_read(&ce->np->kobj.kref) > 1) {527 pr_err("ERROR: memory leak, expected refcount 1 instead of %d, of_node_get()/of_node_put() unbalanced - destroy cset entry: attach overlay node %pOF\n",528 kref_read(&ce->np->kobj.kref), ce->np);529 } else {530 of_node_set_flag(ce->np, OF_OVERLAY_FREE_CSET);531 }532 }533 534 of_node_put(ce->np);535 list_del(&ce->node);536 kfree(ce);537}538 539static void __of_changeset_entry_invert(struct of_changeset_entry *ce,540 struct of_changeset_entry *rce)541{542 memcpy(rce, ce, sizeof(*rce));543 544 switch (ce->action) {545 case OF_RECONFIG_ATTACH_NODE:546 rce->action = OF_RECONFIG_DETACH_NODE;547 break;548 case OF_RECONFIG_DETACH_NODE:549 rce->action = OF_RECONFIG_ATTACH_NODE;550 break;551 case OF_RECONFIG_ADD_PROPERTY:552 rce->action = OF_RECONFIG_REMOVE_PROPERTY;553 break;554 case OF_RECONFIG_REMOVE_PROPERTY:555 rce->action = OF_RECONFIG_ADD_PROPERTY;556 break;557 case OF_RECONFIG_UPDATE_PROPERTY:558 rce->old_prop = ce->prop;559 rce->prop = ce->old_prop;560 /* update was used but original property did not exist */561 if (!rce->prop) {562 rce->action = OF_RECONFIG_REMOVE_PROPERTY;563 rce->prop = ce->prop;564 }565 break;566 }567}568 569static int __of_changeset_entry_notify(struct of_changeset_entry *ce,570 bool revert)571{572 struct of_reconfig_data rd;573 struct of_changeset_entry ce_inverted;574 int ret = 0;575 576 if (revert) {577 __of_changeset_entry_invert(ce, &ce_inverted);578 ce = &ce_inverted;579 }580 581 switch (ce->action) {582 case OF_RECONFIG_ATTACH_NODE:583 case OF_RECONFIG_DETACH_NODE:584 memset(&rd, 0, sizeof(rd));585 rd.dn = ce->np;586 ret = of_reconfig_notify(ce->action, &rd);587 break;588 case OF_RECONFIG_ADD_PROPERTY:589 case OF_RECONFIG_REMOVE_PROPERTY:590 case OF_RECONFIG_UPDATE_PROPERTY:591 ret = of_property_notify(ce->action, ce->np, ce->prop, ce->old_prop);592 break;593 default:594 pr_err("invalid devicetree changeset action: %i\n",595 (int)ce->action);596 ret = -EINVAL;597 }598 599 if (ret)600 pr_err("changeset notifier error @%pOF\n", ce->np);601 return ret;602}603 604static int __of_changeset_entry_apply(struct of_changeset_entry *ce)605{606 int ret = 0;607 608 of_changeset_action_debug("apply: ", ce->action, ce->np, ce->prop);609 610 switch (ce->action) {611 case OF_RECONFIG_ATTACH_NODE:612 __of_attach_node(ce->np);613 break;614 case OF_RECONFIG_DETACH_NODE:615 __of_detach_node(ce->np);616 break;617 case OF_RECONFIG_ADD_PROPERTY:618 ret = __of_add_property(ce->np, ce->prop);619 break;620 case OF_RECONFIG_REMOVE_PROPERTY:621 ret = __of_remove_property(ce->np, ce->prop);622 break;623 624 case OF_RECONFIG_UPDATE_PROPERTY:625 ret = __of_update_property(ce->np, ce->prop, &ce->old_prop);626 break;627 default:628 ret = -EINVAL;629 }630 631 if (ret) {632 of_changeset_action_err("apply failed: ", ce->action, ce->np, ce->prop);633 return ret;634 }635 636 return 0;637}638 639static inline int __of_changeset_entry_revert(struct of_changeset_entry *ce)640{641 struct of_changeset_entry ce_inverted;642 643 __of_changeset_entry_invert(ce, &ce_inverted);644 return __of_changeset_entry_apply(&ce_inverted);645}646 647/**648 * of_changeset_init - Initialize a changeset for use649 *650 * @ocs: changeset pointer651 *652 * Initialize a changeset structure653 */654void of_changeset_init(struct of_changeset *ocs)655{656 memset(ocs, 0, sizeof(*ocs));657 INIT_LIST_HEAD(&ocs->entries);658}659EXPORT_SYMBOL_GPL(of_changeset_init);660 661/**662 * of_changeset_destroy - Destroy a changeset663 *664 * @ocs: changeset pointer665 *666 * Destroys a changeset. Note that if a changeset is applied,667 * its changes to the tree cannot be reverted.668 */669void of_changeset_destroy(struct of_changeset *ocs)670{671 struct of_changeset_entry *ce, *cen;672 673 /*674 * When a device is deleted, the device links to/from it are also queued675 * for deletion. Until these device links are freed, the devices676 * themselves aren't freed. If the device being deleted is due to an677 * overlay change, this device might be holding a reference to a device678 * node that will be freed. So, wait until all already pending device679 * links are deleted before freeing a device node. This ensures we don't680 * free any device node that has a non-zero reference count.681 */682 device_link_wait_removal();683 684 list_for_each_entry_safe_reverse(ce, cen, &ocs->entries, node)685 __of_changeset_entry_destroy(ce);686}687EXPORT_SYMBOL_GPL(of_changeset_destroy);688 689/*690 * Apply the changeset entries in @ocs.691 * If apply fails, an attempt is made to revert the entries that were692 * successfully applied.693 *694 * If multiple revert errors occur then only the final revert error is reported.695 *696 * Returns 0 on success, a negative error value in case of an error.697 * If a revert error occurs, it is returned in *ret_revert.698 */699int __of_changeset_apply_entries(struct of_changeset *ocs, int *ret_revert)700{701 struct of_changeset_entry *ce;702 int ret, ret_tmp;703 704 pr_debug("changeset: applying...\n");705 list_for_each_entry(ce, &ocs->entries, node) {706 ret = __of_changeset_entry_apply(ce);707 if (ret) {708 pr_err("Error applying changeset (%d)\n", ret);709 list_for_each_entry_continue_reverse(ce, &ocs->entries,710 node) {711 ret_tmp = __of_changeset_entry_revert(ce);712 if (ret_tmp)713 *ret_revert = ret_tmp;714 }715 return ret;716 }717 }718 719 return 0;720}721 722/*723 * Returns 0 on success, a negative error value in case of an error.724 *725 * If multiple changeset entry notification errors occur then only the726 * final notification error is reported.727 */728int __of_changeset_apply_notify(struct of_changeset *ocs)729{730 struct of_changeset_entry *ce;731 int ret = 0, ret_tmp;732 733 pr_debug("changeset: emitting notifiers.\n");734 735 /* drop the global lock while emitting notifiers */736 mutex_unlock(&of_mutex);737 list_for_each_entry(ce, &ocs->entries, node) {738 ret_tmp = __of_changeset_entry_notify(ce, 0);739 if (ret_tmp)740 ret = ret_tmp;741 }742 mutex_lock(&of_mutex);743 pr_debug("changeset: notifiers sent.\n");744 745 return ret;746}747 748/*749 * Returns 0 on success, a negative error value in case of an error.750 *751 * If a changeset entry apply fails, an attempt is made to revert any752 * previous entries in the changeset. If any of the reverts fails,753 * that failure is not reported. Thus the state of the device tree754 * is unknown if an apply error occurs.755 */756static int __of_changeset_apply(struct of_changeset *ocs)757{758 int ret, ret_revert = 0;759 760 ret = __of_changeset_apply_entries(ocs, &ret_revert);761 if (!ret)762 ret = __of_changeset_apply_notify(ocs);763 764 return ret;765}766 767/**768 * of_changeset_apply - Applies a changeset769 *770 * @ocs: changeset pointer771 *772 * Applies a changeset to the live tree.773 * Any side-effects of live tree state changes are applied here on774 * success, like creation/destruction of devices and side-effects775 * like creation of sysfs properties and directories.776 *777 * Return: 0 on success, a negative error value in case of an error.778 * On error the partially applied effects are reverted.779 */780int of_changeset_apply(struct of_changeset *ocs)781{782 int ret;783 784 mutex_lock(&of_mutex);785 ret = __of_changeset_apply(ocs);786 mutex_unlock(&of_mutex);787 788 return ret;789}790EXPORT_SYMBOL_GPL(of_changeset_apply);791 792/*793 * Revert the changeset entries in @ocs.794 * If revert fails, an attempt is made to re-apply the entries that were795 * successfully removed.796 *797 * If multiple re-apply errors occur then only the final apply error is798 * reported.799 *800 * Returns 0 on success, a negative error value in case of an error.801 * If an apply error occurs, it is returned in *ret_apply.802 */803int __of_changeset_revert_entries(struct of_changeset *ocs, int *ret_apply)804{805 struct of_changeset_entry *ce;806 int ret, ret_tmp;807 808 pr_debug("changeset: reverting...\n");809 list_for_each_entry_reverse(ce, &ocs->entries, node) {810 ret = __of_changeset_entry_revert(ce);811 if (ret) {812 pr_err("Error reverting changeset (%d)\n", ret);813 list_for_each_entry_continue(ce, &ocs->entries, node) {814 ret_tmp = __of_changeset_entry_apply(ce);815 if (ret_tmp)816 *ret_apply = ret_tmp;817 }818 return ret;819 }820 }821 822 return 0;823}824 825/*826 * If multiple changeset entry notification errors occur then only the827 * final notification error is reported.828 */829int __of_changeset_revert_notify(struct of_changeset *ocs)830{831 struct of_changeset_entry *ce;832 int ret = 0, ret_tmp;833 834 pr_debug("changeset: emitting notifiers.\n");835 836 /* drop the global lock while emitting notifiers */837 mutex_unlock(&of_mutex);838 list_for_each_entry_reverse(ce, &ocs->entries, node) {839 ret_tmp = __of_changeset_entry_notify(ce, 1);840 if (ret_tmp)841 ret = ret_tmp;842 }843 mutex_lock(&of_mutex);844 pr_debug("changeset: notifiers sent.\n");845 846 return ret;847}848 849static int __of_changeset_revert(struct of_changeset *ocs)850{851 int ret, ret_reply;852 853 ret_reply = 0;854 ret = __of_changeset_revert_entries(ocs, &ret_reply);855 856 if (!ret)857 ret = __of_changeset_revert_notify(ocs);858 859 return ret;860}861 862/**863 * of_changeset_revert - Reverts an applied changeset864 *865 * @ocs: changeset pointer866 *867 * Reverts a changeset returning the state of the tree to what it868 * was before the application.869 * Any side-effects like creation/destruction of devices and870 * removal of sysfs properties and directories are applied.871 *872 * Return: 0 on success, a negative error value in case of an error.873 */874int of_changeset_revert(struct of_changeset *ocs)875{876 int ret;877 878 mutex_lock(&of_mutex);879 ret = __of_changeset_revert(ocs);880 mutex_unlock(&of_mutex);881 882 return ret;883}884EXPORT_SYMBOL_GPL(of_changeset_revert);885 886/**887 * of_changeset_action - Add an action to the tail of the changeset list888 *889 * @ocs: changeset pointer890 * @action: action to perform891 * @np: Pointer to device node892 * @prop: Pointer to property893 *894 * On action being one of:895 * + OF_RECONFIG_ATTACH_NODE896 * + OF_RECONFIG_DETACH_NODE,897 * + OF_RECONFIG_ADD_PROPERTY898 * + OF_RECONFIG_REMOVE_PROPERTY,899 * + OF_RECONFIG_UPDATE_PROPERTY900 *901 * Return: 0 on success, a negative error value in case of an error.902 */903int of_changeset_action(struct of_changeset *ocs, unsigned long action,904 struct device_node *np, struct property *prop)905{906 struct of_changeset_entry *ce;907 908 if (WARN_ON(action >= ARRAY_SIZE(action_names)))909 return -EINVAL;910 911 ce = kzalloc(sizeof(*ce), GFP_KERNEL);912 if (!ce)913 return -ENOMEM;914 915 /* get a reference to the node */916 ce->action = action;917 ce->np = of_node_get(np);918 ce->prop = prop;919 920 /* add it to the list */921 list_add_tail(&ce->node, &ocs->entries);922 return 0;923}924EXPORT_SYMBOL_GPL(of_changeset_action);925 926static int of_changeset_add_prop_helper(struct of_changeset *ocs,927 struct device_node *np,928 const struct property *pp)929{930 struct property *new_pp;931 int ret;932 933 new_pp = __of_prop_dup(pp, GFP_KERNEL);934 if (!new_pp)935 return -ENOMEM;936 937 ret = of_changeset_add_property(ocs, np, new_pp);938 if (ret)939 __of_prop_free(new_pp);940 941 return ret;942}943 944/**945 * of_changeset_add_prop_string - Add a string property to a changeset946 *947 * @ocs: changeset pointer948 * @np: device node pointer949 * @prop_name: name of the property to be added950 * @str: pointer to null terminated string951 *952 * Create a string property and add it to a changeset.953 *954 * Return: 0 on success, a negative error value in case of an error.955 */956int of_changeset_add_prop_string(struct of_changeset *ocs,957 struct device_node *np,958 const char *prop_name, const char *str)959{960 struct property prop;961 962 prop.name = (char *)prop_name;963 prop.length = strlen(str) + 1;964 prop.value = (void *)str;965 966 return of_changeset_add_prop_helper(ocs, np, &prop);967}968EXPORT_SYMBOL_GPL(of_changeset_add_prop_string);969 970/**971 * of_changeset_add_prop_string_array - Add a string list property to972 * a changeset973 *974 * @ocs: changeset pointer975 * @np: device node pointer976 * @prop_name: name of the property to be added977 * @str_array: pointer to an array of null terminated strings978 * @sz: number of string array elements979 *980 * Create a string list property and add it to a changeset.981 *982 * Return: 0 on success, a negative error value in case of an error.983 */984int of_changeset_add_prop_string_array(struct of_changeset *ocs,985 struct device_node *np,986 const char *prop_name,987 const char * const *str_array, size_t sz)988{989 struct property prop;990 int i, ret;991 char *vp;992 993 prop.name = (char *)prop_name;994 995 prop.length = 0;996 for (i = 0; i < sz; i++)997 prop.length += strlen(str_array[i]) + 1;998 999 prop.value = kmalloc(prop.length, GFP_KERNEL);1000 if (!prop.value)1001 return -ENOMEM;1002 1003 vp = prop.value;1004 for (i = 0; i < sz; i++) {1005 vp += snprintf(vp, (char *)prop.value + prop.length - vp, "%s",1006 str_array[i]) + 1;1007 }1008 ret = of_changeset_add_prop_helper(ocs, np, &prop);1009 kfree(prop.value);1010 1011 return ret;1012}1013EXPORT_SYMBOL_GPL(of_changeset_add_prop_string_array);1014 1015/**1016 * of_changeset_add_prop_u32_array - Add a property of 32 bit integers1017 * property to a changeset1018 *1019 * @ocs: changeset pointer1020 * @np: device node pointer1021 * @prop_name: name of the property to be added1022 * @array: pointer to an array of 32 bit integers1023 * @sz: number of array elements1024 *1025 * Create a property of 32 bit integers and add it to a changeset.1026 *1027 * Return: 0 on success, a negative error value in case of an error.1028 */1029int of_changeset_add_prop_u32_array(struct of_changeset *ocs,1030 struct device_node *np,1031 const char *prop_name,1032 const u32 *array, size_t sz)1033{1034 struct property prop;1035 __be32 *val __free(kfree) = kcalloc(sz, sizeof(__be32), GFP_KERNEL);1036 int i;1037 1038 if (!val)1039 return -ENOMEM;1040 1041 for (i = 0; i < sz; i++)1042 val[i] = cpu_to_be32(array[i]);1043 prop.name = (char *)prop_name;1044 prop.length = sizeof(u32) * sz;1045 prop.value = (void *)val;1046 1047 return of_changeset_add_prop_helper(ocs, np, &prop);1048}1049EXPORT_SYMBOL_GPL(of_changeset_add_prop_u32_array);1050 1051/**1052 * of_changeset_add_prop_bool - Add a boolean property (i.e. a property without1053 * any values) to a changeset.1054 *1055 * @ocs: changeset pointer1056 * @np: device node pointer1057 * @prop_name: name of the property to be added1058 *1059 * Create a boolean property and add it to a changeset.1060 *1061 * Return: 0 on success, a negative error value in case of an error.1062 */1063int of_changeset_add_prop_bool(struct of_changeset *ocs, struct device_node *np,1064 const char *prop_name)1065{1066 struct property prop;1067 1068 prop.name = (char *)prop_name;1069 prop.length = 0;1070 prop.value = NULL;1071 1072 return of_changeset_add_prop_helper(ocs, np, &prop);1073}1074EXPORT_SYMBOL_GPL(of_changeset_add_prop_bool);1075