0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #define pr_fmt(fmt) "OF: " fmt
0011
0012 #include <linux/of.h>
0013 #include <linux/spinlock.h>
0014 #include <linux/slab.h>
0015 #include <linux/string.h>
0016 #include <linux/proc_fs.h>
0017
0018 #include "of_private.h"
0019
0020 static struct device_node *kobj_to_device_node(struct kobject *kobj)
0021 {
0022 return container_of(kobj, struct device_node, kobj);
0023 }
0024
0025
0026
0027
0028
0029
0030
0031
0032 struct device_node *of_node_get(struct device_node *node)
0033 {
0034 if (node)
0035 kobject_get(&node->kobj);
0036 return node;
0037 }
0038 EXPORT_SYMBOL(of_node_get);
0039
0040
0041
0042
0043
0044
0045 void of_node_put(struct device_node *node)
0046 {
0047 if (node)
0048 kobject_put(&node->kobj);
0049 }
0050 EXPORT_SYMBOL(of_node_put);
0051
0052 static BLOCKING_NOTIFIER_HEAD(of_reconfig_chain);
0053
0054 int of_reconfig_notifier_register(struct notifier_block *nb)
0055 {
0056 return blocking_notifier_chain_register(&of_reconfig_chain, nb);
0057 }
0058 EXPORT_SYMBOL_GPL(of_reconfig_notifier_register);
0059
0060 int of_reconfig_notifier_unregister(struct notifier_block *nb)
0061 {
0062 return blocking_notifier_chain_unregister(&of_reconfig_chain, nb);
0063 }
0064 EXPORT_SYMBOL_GPL(of_reconfig_notifier_unregister);
0065
0066 #ifdef DEBUG
0067 const char *action_names[] = {
0068 [OF_RECONFIG_ATTACH_NODE] = "ATTACH_NODE",
0069 [OF_RECONFIG_DETACH_NODE] = "DETACH_NODE",
0070 [OF_RECONFIG_ADD_PROPERTY] = "ADD_PROPERTY",
0071 [OF_RECONFIG_REMOVE_PROPERTY] = "REMOVE_PROPERTY",
0072 [OF_RECONFIG_UPDATE_PROPERTY] = "UPDATE_PROPERTY",
0073 };
0074 #endif
0075
0076 int of_reconfig_notify(unsigned long action, struct of_reconfig_data *p)
0077 {
0078 int rc;
0079 #ifdef DEBUG
0080 struct of_reconfig_data *pr = p;
0081
0082 switch (action) {
0083 case OF_RECONFIG_ATTACH_NODE:
0084 case OF_RECONFIG_DETACH_NODE:
0085 pr_debug("notify %-15s %pOF\n", action_names[action],
0086 pr->dn);
0087 break;
0088 case OF_RECONFIG_ADD_PROPERTY:
0089 case OF_RECONFIG_REMOVE_PROPERTY:
0090 case OF_RECONFIG_UPDATE_PROPERTY:
0091 pr_debug("notify %-15s %pOF:%s\n", action_names[action],
0092 pr->dn, pr->prop->name);
0093 break;
0094
0095 }
0096 #endif
0097 rc = blocking_notifier_call_chain(&of_reconfig_chain, action, p);
0098 return notifier_to_errno(rc);
0099 }
0100
0101
0102
0103
0104
0105
0106
0107
0108
0109
0110
0111 int of_reconfig_get_state_change(unsigned long action, struct of_reconfig_data *pr)
0112 {
0113 struct property *prop, *old_prop = NULL;
0114 int is_status, status_state, old_status_state, prev_state, new_state;
0115
0116
0117 switch (action) {
0118 case OF_RECONFIG_ATTACH_NODE:
0119 case OF_RECONFIG_DETACH_NODE:
0120 prop = of_find_property(pr->dn, "status", NULL);
0121 break;
0122 case OF_RECONFIG_ADD_PROPERTY:
0123 case OF_RECONFIG_REMOVE_PROPERTY:
0124 prop = pr->prop;
0125 break;
0126 case OF_RECONFIG_UPDATE_PROPERTY:
0127 prop = pr->prop;
0128 old_prop = pr->old_prop;
0129 break;
0130 default:
0131 return OF_RECONFIG_NO_CHANGE;
0132 }
0133
0134 is_status = 0;
0135 status_state = -1;
0136 old_status_state = -1;
0137 prev_state = -1;
0138 new_state = -1;
0139
0140 if (prop && !strcmp(prop->name, "status")) {
0141 is_status = 1;
0142 status_state = !strcmp(prop->value, "okay") ||
0143 !strcmp(prop->value, "ok");
0144 if (old_prop)
0145 old_status_state = !strcmp(old_prop->value, "okay") ||
0146 !strcmp(old_prop->value, "ok");
0147 }
0148
0149 switch (action) {
0150 case OF_RECONFIG_ATTACH_NODE:
0151 prev_state = 0;
0152
0153 new_state = status_state != 0;
0154 break;
0155 case OF_RECONFIG_DETACH_NODE:
0156
0157 prev_state = status_state != 0;
0158 new_state = 0;
0159 break;
0160 case OF_RECONFIG_ADD_PROPERTY:
0161 if (is_status) {
0162
0163 prev_state = 1;
0164 new_state = status_state;
0165 }
0166 break;
0167 case OF_RECONFIG_REMOVE_PROPERTY:
0168 if (is_status) {
0169 prev_state = status_state;
0170
0171 new_state = 1;
0172 }
0173 break;
0174 case OF_RECONFIG_UPDATE_PROPERTY:
0175 if (is_status) {
0176 prev_state = old_status_state != 0;
0177 new_state = status_state != 0;
0178 }
0179 break;
0180 }
0181
0182 if (prev_state == new_state)
0183 return OF_RECONFIG_NO_CHANGE;
0184
0185 return new_state ? OF_RECONFIG_CHANGE_ADD : OF_RECONFIG_CHANGE_REMOVE;
0186 }
0187 EXPORT_SYMBOL_GPL(of_reconfig_get_state_change);
0188
0189 int of_property_notify(int action, struct device_node *np,
0190 struct property *prop, struct property *oldprop)
0191 {
0192 struct of_reconfig_data pr;
0193
0194
0195 if (!of_node_is_attached(np))
0196 return 0;
0197
0198 pr.dn = np;
0199 pr.prop = prop;
0200 pr.old_prop = oldprop;
0201 return of_reconfig_notify(action, &pr);
0202 }
0203
0204 static void __of_attach_node(struct device_node *np)
0205 {
0206 const __be32 *phandle;
0207 int sz;
0208
0209 if (!of_node_check_flag(np, OF_OVERLAY)) {
0210 np->name = __of_get_property(np, "name", NULL);
0211 if (!np->name)
0212 np->name = "<NULL>";
0213
0214 phandle = __of_get_property(np, "phandle", &sz);
0215 if (!phandle)
0216 phandle = __of_get_property(np, "linux,phandle", &sz);
0217 if (IS_ENABLED(CONFIG_PPC_PSERIES) && !phandle)
0218 phandle = __of_get_property(np, "ibm,phandle", &sz);
0219 if (phandle && (sz >= 4))
0220 np->phandle = be32_to_cpup(phandle);
0221 else
0222 np->phandle = 0;
0223 }
0224
0225 np->child = NULL;
0226 np->sibling = np->parent->child;
0227 np->parent->child = np;
0228 of_node_clear_flag(np, OF_DETACHED);
0229 }
0230
0231
0232
0233
0234
0235 int of_attach_node(struct device_node *np)
0236 {
0237 struct of_reconfig_data rd;
0238 unsigned long flags;
0239
0240 memset(&rd, 0, sizeof(rd));
0241 rd.dn = np;
0242
0243 mutex_lock(&of_mutex);
0244 raw_spin_lock_irqsave(&devtree_lock, flags);
0245 __of_attach_node(np);
0246 raw_spin_unlock_irqrestore(&devtree_lock, flags);
0247
0248 __of_attach_node_sysfs(np);
0249 mutex_unlock(&of_mutex);
0250
0251 of_reconfig_notify(OF_RECONFIG_ATTACH_NODE, &rd);
0252
0253 return 0;
0254 }
0255
0256 void __of_detach_node(struct device_node *np)
0257 {
0258 struct device_node *parent;
0259
0260 if (WARN_ON(of_node_check_flag(np, OF_DETACHED)))
0261 return;
0262
0263 parent = np->parent;
0264 if (WARN_ON(!parent))
0265 return;
0266
0267 if (parent->child == np)
0268 parent->child = np->sibling;
0269 else {
0270 struct device_node *prevsib;
0271 for (prevsib = np->parent->child;
0272 prevsib->sibling != np;
0273 prevsib = prevsib->sibling)
0274 ;
0275 prevsib->sibling = np->sibling;
0276 }
0277
0278 of_node_set_flag(np, OF_DETACHED);
0279
0280
0281 __of_phandle_cache_inv_entry(np->phandle);
0282 }
0283
0284
0285
0286
0287
0288 int of_detach_node(struct device_node *np)
0289 {
0290 struct of_reconfig_data rd;
0291 unsigned long flags;
0292
0293 memset(&rd, 0, sizeof(rd));
0294 rd.dn = np;
0295
0296 mutex_lock(&of_mutex);
0297 raw_spin_lock_irqsave(&devtree_lock, flags);
0298 __of_detach_node(np);
0299 raw_spin_unlock_irqrestore(&devtree_lock, flags);
0300
0301 __of_detach_node_sysfs(np);
0302 mutex_unlock(&of_mutex);
0303
0304 of_reconfig_notify(OF_RECONFIG_DETACH_NODE, &rd);
0305
0306 return 0;
0307 }
0308 EXPORT_SYMBOL_GPL(of_detach_node);
0309
0310 static void property_list_free(struct property *prop_list)
0311 {
0312 struct property *prop, *next;
0313
0314 for (prop = prop_list; prop != NULL; prop = next) {
0315 next = prop->next;
0316 kfree(prop->name);
0317 kfree(prop->value);
0318 kfree(prop);
0319 }
0320 }
0321
0322
0323
0324
0325
0326
0327
0328 void of_node_release(struct kobject *kobj)
0329 {
0330 struct device_node *node = kobj_to_device_node(kobj);
0331
0332
0333 if (!of_node_check_flag(node, OF_DETACHED)) {
0334 pr_err("ERROR: Bad of_node_put() on %pOF\n", node);
0335 dump_stack();
0336 return;
0337 }
0338 if (!of_node_check_flag(node, OF_DYNAMIC))
0339 return;
0340
0341 if (of_node_check_flag(node, OF_OVERLAY)) {
0342
0343 if (!of_node_check_flag(node, OF_OVERLAY_FREE_CSET)) {
0344
0345 pr_err("ERROR: memory leak before free overlay changeset, %pOF\n",
0346 node);
0347 return;
0348 }
0349
0350
0351
0352
0353
0354
0355 if (node->properties)
0356 pr_err("ERROR: %s(), unexpected properties in %pOF\n",
0357 __func__, node);
0358 }
0359
0360 property_list_free(node->properties);
0361 property_list_free(node->deadprops);
0362 fwnode_links_purge(of_fwnode_handle(node));
0363
0364 kfree(node->full_name);
0365 kfree(node->data);
0366 kfree(node);
0367 }
0368
0369
0370
0371
0372
0373
0374
0375
0376
0377
0378
0379
0380
0381 struct property *__of_prop_dup(const struct property *prop, gfp_t allocflags)
0382 {
0383 struct property *new;
0384
0385 new = kzalloc(sizeof(*new), allocflags);
0386 if (!new)
0387 return NULL;
0388
0389
0390
0391
0392
0393
0394
0395 new->name = kstrdup(prop->name, allocflags);
0396 new->value = kmemdup(prop->value, prop->length, allocflags);
0397 new->length = prop->length;
0398 if (!new->name || !new->value)
0399 goto err_free;
0400
0401
0402 of_property_set_flag(new, OF_DYNAMIC);
0403
0404 return new;
0405
0406 err_free:
0407 kfree(new->name);
0408 kfree(new->value);
0409 kfree(new);
0410 return NULL;
0411 }
0412
0413
0414
0415
0416
0417
0418
0419
0420
0421
0422
0423
0424 struct device_node *__of_node_dup(const struct device_node *np,
0425 const char *full_name)
0426 {
0427 struct device_node *node;
0428
0429 node = kzalloc(sizeof(*node), GFP_KERNEL);
0430 if (!node)
0431 return NULL;
0432 node->full_name = kstrdup(full_name, GFP_KERNEL);
0433 if (!node->full_name) {
0434 kfree(node);
0435 return NULL;
0436 }
0437
0438 of_node_set_flag(node, OF_DYNAMIC);
0439 of_node_set_flag(node, OF_DETACHED);
0440 of_node_init(node);
0441
0442
0443 if (np) {
0444 struct property *pp, *new_pp;
0445 for_each_property_of_node(np, pp) {
0446 new_pp = __of_prop_dup(pp, GFP_KERNEL);
0447 if (!new_pp)
0448 goto err_prop;
0449 if (__of_add_property(node, new_pp)) {
0450 kfree(new_pp->name);
0451 kfree(new_pp->value);
0452 kfree(new_pp);
0453 goto err_prop;
0454 }
0455 }
0456 }
0457 return node;
0458
0459 err_prop:
0460 of_node_put(node);
0461 return NULL;
0462 }
0463
0464 static void __of_changeset_entry_destroy(struct of_changeset_entry *ce)
0465 {
0466 if (ce->action == OF_RECONFIG_ATTACH_NODE &&
0467 of_node_check_flag(ce->np, OF_OVERLAY)) {
0468 if (kref_read(&ce->np->kobj.kref) > 1) {
0469 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",
0470 kref_read(&ce->np->kobj.kref), ce->np);
0471 } else {
0472 of_node_set_flag(ce->np, OF_OVERLAY_FREE_CSET);
0473 }
0474 }
0475
0476 of_node_put(ce->np);
0477 list_del(&ce->node);
0478 kfree(ce);
0479 }
0480
0481 #ifdef DEBUG
0482 static void __of_changeset_entry_dump(struct of_changeset_entry *ce)
0483 {
0484 switch (ce->action) {
0485 case OF_RECONFIG_ADD_PROPERTY:
0486 case OF_RECONFIG_REMOVE_PROPERTY:
0487 case OF_RECONFIG_UPDATE_PROPERTY:
0488 pr_debug("cset<%p> %-15s %pOF/%s\n", ce, action_names[ce->action],
0489 ce->np, ce->prop->name);
0490 break;
0491 case OF_RECONFIG_ATTACH_NODE:
0492 case OF_RECONFIG_DETACH_NODE:
0493 pr_debug("cset<%p> %-15s %pOF\n", ce, action_names[ce->action],
0494 ce->np);
0495 break;
0496 }
0497 }
0498 #else
0499 static inline void __of_changeset_entry_dump(struct of_changeset_entry *ce)
0500 {
0501
0502 }
0503 #endif
0504
0505 static void __of_changeset_entry_invert(struct of_changeset_entry *ce,
0506 struct of_changeset_entry *rce)
0507 {
0508 memcpy(rce, ce, sizeof(*rce));
0509
0510 switch (ce->action) {
0511 case OF_RECONFIG_ATTACH_NODE:
0512 rce->action = OF_RECONFIG_DETACH_NODE;
0513 break;
0514 case OF_RECONFIG_DETACH_NODE:
0515 rce->action = OF_RECONFIG_ATTACH_NODE;
0516 break;
0517 case OF_RECONFIG_ADD_PROPERTY:
0518 rce->action = OF_RECONFIG_REMOVE_PROPERTY;
0519 break;
0520 case OF_RECONFIG_REMOVE_PROPERTY:
0521 rce->action = OF_RECONFIG_ADD_PROPERTY;
0522 break;
0523 case OF_RECONFIG_UPDATE_PROPERTY:
0524 rce->old_prop = ce->prop;
0525 rce->prop = ce->old_prop;
0526
0527 if (!rce->prop) {
0528 rce->action = OF_RECONFIG_REMOVE_PROPERTY;
0529 rce->prop = ce->prop;
0530 }
0531 break;
0532 }
0533 }
0534
0535 static int __of_changeset_entry_notify(struct of_changeset_entry *ce,
0536 bool revert)
0537 {
0538 struct of_reconfig_data rd;
0539 struct of_changeset_entry ce_inverted;
0540 int ret = 0;
0541
0542 if (revert) {
0543 __of_changeset_entry_invert(ce, &ce_inverted);
0544 ce = &ce_inverted;
0545 }
0546
0547 switch (ce->action) {
0548 case OF_RECONFIG_ATTACH_NODE:
0549 case OF_RECONFIG_DETACH_NODE:
0550 memset(&rd, 0, sizeof(rd));
0551 rd.dn = ce->np;
0552 ret = of_reconfig_notify(ce->action, &rd);
0553 break;
0554 case OF_RECONFIG_ADD_PROPERTY:
0555 case OF_RECONFIG_REMOVE_PROPERTY:
0556 case OF_RECONFIG_UPDATE_PROPERTY:
0557 ret = of_property_notify(ce->action, ce->np, ce->prop, ce->old_prop);
0558 break;
0559 default:
0560 pr_err("invalid devicetree changeset action: %i\n",
0561 (int)ce->action);
0562 ret = -EINVAL;
0563 }
0564
0565 if (ret)
0566 pr_err("changeset notifier error @%pOF\n", ce->np);
0567 return ret;
0568 }
0569
0570 static int __of_changeset_entry_apply(struct of_changeset_entry *ce)
0571 {
0572 struct property *old_prop, **propp;
0573 unsigned long flags;
0574 int ret = 0;
0575
0576 __of_changeset_entry_dump(ce);
0577
0578 raw_spin_lock_irqsave(&devtree_lock, flags);
0579 switch (ce->action) {
0580 case OF_RECONFIG_ATTACH_NODE:
0581 __of_attach_node(ce->np);
0582 break;
0583 case OF_RECONFIG_DETACH_NODE:
0584 __of_detach_node(ce->np);
0585 break;
0586 case OF_RECONFIG_ADD_PROPERTY:
0587
0588 for (propp = &ce->np->deadprops; *propp; propp = &(*propp)->next) {
0589 if (*propp == ce->prop) {
0590 *propp = ce->prop->next;
0591 ce->prop->next = NULL;
0592 break;
0593 }
0594 }
0595
0596 ret = __of_add_property(ce->np, ce->prop);
0597 if (ret) {
0598 pr_err("changeset: add_property failed @%pOF/%s\n",
0599 ce->np,
0600 ce->prop->name);
0601 break;
0602 }
0603 break;
0604 case OF_RECONFIG_REMOVE_PROPERTY:
0605 ret = __of_remove_property(ce->np, ce->prop);
0606 if (ret) {
0607 pr_err("changeset: remove_property failed @%pOF/%s\n",
0608 ce->np,
0609 ce->prop->name);
0610 break;
0611 }
0612 break;
0613
0614 case OF_RECONFIG_UPDATE_PROPERTY:
0615
0616 for (propp = &ce->np->deadprops; *propp; propp = &(*propp)->next) {
0617 if (*propp == ce->prop) {
0618 *propp = ce->prop->next;
0619 ce->prop->next = NULL;
0620 break;
0621 }
0622 }
0623
0624 ret = __of_update_property(ce->np, ce->prop, &old_prop);
0625 if (ret) {
0626 pr_err("changeset: update_property failed @%pOF/%s\n",
0627 ce->np,
0628 ce->prop->name);
0629 break;
0630 }
0631 break;
0632 default:
0633 ret = -EINVAL;
0634 }
0635 raw_spin_unlock_irqrestore(&devtree_lock, flags);
0636
0637 if (ret)
0638 return ret;
0639
0640 switch (ce->action) {
0641 case OF_RECONFIG_ATTACH_NODE:
0642 __of_attach_node_sysfs(ce->np);
0643 break;
0644 case OF_RECONFIG_DETACH_NODE:
0645 __of_detach_node_sysfs(ce->np);
0646 break;
0647 case OF_RECONFIG_ADD_PROPERTY:
0648
0649 __of_add_property_sysfs(ce->np, ce->prop);
0650 break;
0651 case OF_RECONFIG_REMOVE_PROPERTY:
0652 __of_remove_property_sysfs(ce->np, ce->prop);
0653 break;
0654 case OF_RECONFIG_UPDATE_PROPERTY:
0655 __of_update_property_sysfs(ce->np, ce->prop, ce->old_prop);
0656 break;
0657 }
0658
0659 return 0;
0660 }
0661
0662 static inline int __of_changeset_entry_revert(struct of_changeset_entry *ce)
0663 {
0664 struct of_changeset_entry ce_inverted;
0665
0666 __of_changeset_entry_invert(ce, &ce_inverted);
0667 return __of_changeset_entry_apply(&ce_inverted);
0668 }
0669
0670
0671
0672
0673
0674
0675
0676
0677 void of_changeset_init(struct of_changeset *ocs)
0678 {
0679 memset(ocs, 0, sizeof(*ocs));
0680 INIT_LIST_HEAD(&ocs->entries);
0681 }
0682 EXPORT_SYMBOL_GPL(of_changeset_init);
0683
0684
0685
0686
0687
0688
0689
0690
0691
0692 void of_changeset_destroy(struct of_changeset *ocs)
0693 {
0694 struct of_changeset_entry *ce, *cen;
0695
0696 list_for_each_entry_safe_reverse(ce, cen, &ocs->entries, node)
0697 __of_changeset_entry_destroy(ce);
0698 }
0699 EXPORT_SYMBOL_GPL(of_changeset_destroy);
0700
0701
0702
0703
0704
0705
0706
0707
0708
0709
0710
0711 int __of_changeset_apply_entries(struct of_changeset *ocs, int *ret_revert)
0712 {
0713 struct of_changeset_entry *ce;
0714 int ret, ret_tmp;
0715
0716 pr_debug("changeset: applying...\n");
0717 list_for_each_entry(ce, &ocs->entries, node) {
0718 ret = __of_changeset_entry_apply(ce);
0719 if (ret) {
0720 pr_err("Error applying changeset (%d)\n", ret);
0721 list_for_each_entry_continue_reverse(ce, &ocs->entries,
0722 node) {
0723 ret_tmp = __of_changeset_entry_revert(ce);
0724 if (ret_tmp)
0725 *ret_revert = ret_tmp;
0726 }
0727 return ret;
0728 }
0729 }
0730
0731 return 0;
0732 }
0733
0734
0735
0736
0737
0738
0739
0740 int __of_changeset_apply_notify(struct of_changeset *ocs)
0741 {
0742 struct of_changeset_entry *ce;
0743 int ret = 0, ret_tmp;
0744
0745 pr_debug("changeset: emitting notifiers.\n");
0746
0747
0748 mutex_unlock(&of_mutex);
0749 list_for_each_entry(ce, &ocs->entries, node) {
0750 ret_tmp = __of_changeset_entry_notify(ce, 0);
0751 if (ret_tmp)
0752 ret = ret_tmp;
0753 }
0754 mutex_lock(&of_mutex);
0755 pr_debug("changeset: notifiers sent.\n");
0756
0757 return ret;
0758 }
0759
0760
0761
0762
0763
0764
0765
0766
0767
0768 static int __of_changeset_apply(struct of_changeset *ocs)
0769 {
0770 int ret, ret_revert = 0;
0771
0772 ret = __of_changeset_apply_entries(ocs, &ret_revert);
0773 if (!ret)
0774 ret = __of_changeset_apply_notify(ocs);
0775
0776 return ret;
0777 }
0778
0779
0780
0781
0782
0783
0784
0785
0786
0787
0788
0789
0790
0791
0792 int of_changeset_apply(struct of_changeset *ocs)
0793 {
0794 int ret;
0795
0796 mutex_lock(&of_mutex);
0797 ret = __of_changeset_apply(ocs);
0798 mutex_unlock(&of_mutex);
0799
0800 return ret;
0801 }
0802 EXPORT_SYMBOL_GPL(of_changeset_apply);
0803
0804
0805
0806
0807
0808
0809
0810
0811
0812
0813
0814
0815 int __of_changeset_revert_entries(struct of_changeset *ocs, int *ret_apply)
0816 {
0817 struct of_changeset_entry *ce;
0818 int ret, ret_tmp;
0819
0820 pr_debug("changeset: reverting...\n");
0821 list_for_each_entry_reverse(ce, &ocs->entries, node) {
0822 ret = __of_changeset_entry_revert(ce);
0823 if (ret) {
0824 pr_err("Error reverting changeset (%d)\n", ret);
0825 list_for_each_entry_continue(ce, &ocs->entries, node) {
0826 ret_tmp = __of_changeset_entry_apply(ce);
0827 if (ret_tmp)
0828 *ret_apply = ret_tmp;
0829 }
0830 return ret;
0831 }
0832 }
0833
0834 return 0;
0835 }
0836
0837
0838
0839
0840
0841 int __of_changeset_revert_notify(struct of_changeset *ocs)
0842 {
0843 struct of_changeset_entry *ce;
0844 int ret = 0, ret_tmp;
0845
0846 pr_debug("changeset: emitting notifiers.\n");
0847
0848
0849 mutex_unlock(&of_mutex);
0850 list_for_each_entry_reverse(ce, &ocs->entries, node) {
0851 ret_tmp = __of_changeset_entry_notify(ce, 1);
0852 if (ret_tmp)
0853 ret = ret_tmp;
0854 }
0855 mutex_lock(&of_mutex);
0856 pr_debug("changeset: notifiers sent.\n");
0857
0858 return ret;
0859 }
0860
0861 static int __of_changeset_revert(struct of_changeset *ocs)
0862 {
0863 int ret, ret_reply;
0864
0865 ret_reply = 0;
0866 ret = __of_changeset_revert_entries(ocs, &ret_reply);
0867
0868 if (!ret)
0869 ret = __of_changeset_revert_notify(ocs);
0870
0871 return ret;
0872 }
0873
0874
0875
0876
0877
0878
0879
0880
0881
0882
0883
0884
0885
0886 int of_changeset_revert(struct of_changeset *ocs)
0887 {
0888 int ret;
0889
0890 mutex_lock(&of_mutex);
0891 ret = __of_changeset_revert(ocs);
0892 mutex_unlock(&of_mutex);
0893
0894 return ret;
0895 }
0896 EXPORT_SYMBOL_GPL(of_changeset_revert);
0897
0898
0899
0900
0901
0902
0903
0904
0905
0906
0907
0908
0909
0910
0911
0912
0913
0914
0915 int of_changeset_action(struct of_changeset *ocs, unsigned long action,
0916 struct device_node *np, struct property *prop)
0917 {
0918 struct of_changeset_entry *ce;
0919
0920 ce = kzalloc(sizeof(*ce), GFP_KERNEL);
0921 if (!ce)
0922 return -ENOMEM;
0923
0924
0925 ce->action = action;
0926 ce->np = of_node_get(np);
0927 ce->prop = prop;
0928
0929 if (action == OF_RECONFIG_UPDATE_PROPERTY && prop)
0930 ce->old_prop = of_find_property(np, prop->name, NULL);
0931
0932
0933 list_add_tail(&ce->node, &ocs->entries);
0934 return 0;
0935 }
0936 EXPORT_SYMBOL_GPL(of_changeset_action);