]> Git Repo - linux.git/blame - drivers/of/dynamic.c
of: dynamic: Refactor changeset action printing to common helpers
[linux.git] / drivers / of / dynamic.c
CommitLineData
af6074fc 1// SPDX-License-Identifier: GPL-2.0
6afc0dc3
GL
2/*
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 changing
7 * device tree nodes.
8 */
9
606ad42a
RH
10#define pr_fmt(fmt) "OF: " fmt
11
6afc0dc3
GL
12#include <linux/of.h>
13#include <linux/spinlock.h>
14#include <linux/slab.h>
15#include <linux/string.h>
16#include <linux/proc_fs.h>
17
18#include "of_private.h"
19
4c2bb574
RH
20static struct device_node *kobj_to_device_node(struct kobject *kobj)
21{
22 return container_of(kobj, struct device_node, kobj);
23}
24
6afc0dc3
GL
25/**
26 * of_node_get() - Increment refcount of a node
27 * @node: Node to inc refcount, NULL is supported to simplify writing of
28 * callers
29 *
8c8239c2 30 * Return: The node with refcount incremented.
6afc0dc3
GL
31 */
32struct device_node *of_node_get(struct device_node *node)
33{
34 if (node)
35 kobject_get(&node->kobj);
36 return node;
37}
38EXPORT_SYMBOL(of_node_get);
39
40/**
41 * of_node_put() - Decrement refcount of a node
42 * @node: Node to dec refcount, NULL is supported to simplify writing of
43 * callers
44 */
45void of_node_put(struct device_node *node)
46{
47 if (node)
48 kobject_put(&node->kobj);
49}
50EXPORT_SYMBOL(of_node_put);
51
6afc0dc3
GL
52static BLOCKING_NOTIFIER_HEAD(of_reconfig_chain);
53
54int of_reconfig_notifier_register(struct notifier_block *nb)
55{
56 return blocking_notifier_chain_register(&of_reconfig_chain, nb);
57}
58EXPORT_SYMBOL_GPL(of_reconfig_notifier_register);
59
60int of_reconfig_notifier_unregister(struct notifier_block *nb)
61{
62 return blocking_notifier_chain_unregister(&of_reconfig_chain, nb);
63}
64EXPORT_SYMBOL_GPL(of_reconfig_notifier_unregister);
65
914d9d83
RH
66static const char *action_names[] = {
67 [0] = "INVALID",
00aa3720
GL
68 [OF_RECONFIG_ATTACH_NODE] = "ATTACH_NODE",
69 [OF_RECONFIG_DETACH_NODE] = "DETACH_NODE",
70 [OF_RECONFIG_ADD_PROPERTY] = "ADD_PROPERTY",
71 [OF_RECONFIG_REMOVE_PROPERTY] = "REMOVE_PROPERTY",
72 [OF_RECONFIG_UPDATE_PROPERTY] = "UPDATE_PROPERTY",
73};
00aa3720 74
27a02f26
RH
75#define _do_print(func, prefix, action, node, prop, ...) ({ \
76 func("changeset: " prefix "%-15s %pOF%s%s\n", \
77 ##__VA_ARGS__, action_names[action], node, \
78 prop ? ":" : "", prop ? prop->name : ""); \
79})
80#define of_changeset_action_err(...) _do_print(pr_err, __VA_ARGS__)
81#define of_changeset_action_debug(...) _do_print(pr_debug, __VA_ARGS__)
82
f5242e5a 83int of_reconfig_notify(unsigned long action, struct of_reconfig_data *p)
6afc0dc3
GL
84{
85 int rc;
f5242e5a 86 struct of_reconfig_data *pr = p;
00aa3720 87
27a02f26 88 of_changeset_action_debug("notify: ", action, pr->dn, pr->prop);
6afc0dc3
GL
89
90 rc = blocking_notifier_call_chain(&of_reconfig_chain, action, p);
91 return notifier_to_errno(rc);
92}
93
b53a2340
PA
94/*
95 * of_reconfig_get_state_change() - Returns new state of device
96 * @action - action of the of notifier
97 * @arg - argument of the of notifier
98 *
99 * Returns the new state of a device based on the notifier used.
8c8239c2
RH
100 *
101 * Return: 0 on device going from enabled to disabled, 1 on device
b53a2340
PA
102 * going from disabled to enabled and -1 on no change.
103 */
f5242e5a 104int of_reconfig_get_state_change(unsigned long action, struct of_reconfig_data *pr)
b53a2340 105{
f5242e5a 106 struct property *prop, *old_prop = NULL;
b53a2340
PA
107 int is_status, status_state, old_status_state, prev_state, new_state;
108
109 /* figure out if a device should be created or destroyed */
b53a2340
PA
110 switch (action) {
111 case OF_RECONFIG_ATTACH_NODE:
112 case OF_RECONFIG_DETACH_NODE:
f5242e5a 113 prop = of_find_property(pr->dn, "status", NULL);
b53a2340
PA
114 break;
115 case OF_RECONFIG_ADD_PROPERTY:
116 case OF_RECONFIG_REMOVE_PROPERTY:
b53a2340
PA
117 prop = pr->prop;
118 break;
119 case OF_RECONFIG_UPDATE_PROPERTY:
b53a2340
PA
120 prop = pr->prop;
121 old_prop = pr->old_prop;
122 break;
123 default:
124 return OF_RECONFIG_NO_CHANGE;
125 }
126
127 is_status = 0;
128 status_state = -1;
129 old_status_state = -1;
130 prev_state = -1;
131 new_state = -1;
132
133 if (prop && !strcmp(prop->name, "status")) {
134 is_status = 1;
135 status_state = !strcmp(prop->value, "okay") ||
136 !strcmp(prop->value, "ok");
137 if (old_prop)
138 old_status_state = !strcmp(old_prop->value, "okay") ||
139 !strcmp(old_prop->value, "ok");
140 }
141
142 switch (action) {
143 case OF_RECONFIG_ATTACH_NODE:
144 prev_state = 0;
145 /* -1 & 0 status either missing or okay */
146 new_state = status_state != 0;
147 break;
148 case OF_RECONFIG_DETACH_NODE:
149 /* -1 & 0 status either missing or okay */
150 prev_state = status_state != 0;
151 new_state = 0;
152 break;
153 case OF_RECONFIG_ADD_PROPERTY:
154 if (is_status) {
155 /* no status property -> enabled (legacy) */
156 prev_state = 1;
157 new_state = status_state;
158 }
159 break;
160 case OF_RECONFIG_REMOVE_PROPERTY:
161 if (is_status) {
162 prev_state = status_state;
163 /* no status property -> enabled (legacy) */
164 new_state = 1;
165 }
166 break;
167 case OF_RECONFIG_UPDATE_PROPERTY:
168 if (is_status) {
169 prev_state = old_status_state != 0;
170 new_state = status_state != 0;
171 }
172 break;
173 }
174
175 if (prev_state == new_state)
176 return OF_RECONFIG_NO_CHANGE;
177
178 return new_state ? OF_RECONFIG_CHANGE_ADD : OF_RECONFIG_CHANGE_REMOVE;
179}
180EXPORT_SYMBOL_GPL(of_reconfig_get_state_change);
181
6afc0dc3 182int of_property_notify(int action, struct device_node *np,
259092a3 183 struct property *prop, struct property *oldprop)
6afc0dc3 184{
f5242e5a 185 struct of_reconfig_data pr;
6afc0dc3
GL
186
187 /* only call notifiers if the node is attached */
188 if (!of_node_is_attached(np))
189 return 0;
190
191 pr.dn = np;
192 pr.prop = prop;
259092a3 193 pr.old_prop = oldprop;
6afc0dc3
GL
194 return of_reconfig_notify(action, &pr);
195}
196
24996951 197static void __of_attach_node(struct device_node *np)
d8c50088 198{
a25095d4
GL
199 const __be32 *phandle;
200 int sz;
201
f9627881
FR
202 if (!of_node_check_flag(np, OF_OVERLAY)) {
203 np->name = __of_get_property(np, "name", NULL);
f9627881
FR
204 if (!np->name)
205 np->name = "<NULL>";
f9627881
FR
206
207 phandle = __of_get_property(np, "phandle", &sz);
208 if (!phandle)
209 phandle = __of_get_property(np, "linux,phandle", &sz);
210 if (IS_ENABLED(CONFIG_PPC_PSERIES) && !phandle)
211 phandle = __of_get_property(np, "ibm,phandle", &sz);
212 if (phandle && (sz >= 4))
213 np->phandle = be32_to_cpup(phandle);
214 else
215 np->phandle = 0;
216 }
a25095d4 217
6162dbe4 218 np->child = NULL;
d8c50088 219 np->sibling = np->parent->child;
d8c50088
PA
220 np->parent->child = np;
221 of_node_clear_flag(np, OF_DETACHED);
1a50d940 222 np->fwnode.flags |= FWNODE_FLAG_NOT_DEVICE;
d8c50088
PA
223}
224
6afc0dc3
GL
225/**
226 * of_attach_node() - Plug a device node into the tree and global list.
3cb025d9 227 * @np: Pointer to the caller's Device Node
6afc0dc3
GL
228 */
229int of_attach_node(struct device_node *np)
230{
f5242e5a 231 struct of_reconfig_data rd;
6afc0dc3 232 unsigned long flags;
6afc0dc3 233
f5242e5a
GL
234 memset(&rd, 0, sizeof(rd));
235 rd.dn = np;
236
8a2b22a2 237 mutex_lock(&of_mutex);
6afc0dc3 238 raw_spin_lock_irqsave(&devtree_lock, flags);
d8c50088 239 __of_attach_node(np);
6afc0dc3
GL
240 raw_spin_unlock_irqrestore(&devtree_lock, flags);
241
8a2b22a2
GL
242 __of_attach_node_sysfs(np);
243 mutex_unlock(&of_mutex);
259092a3 244
f5242e5a 245 of_reconfig_notify(OF_RECONFIG_ATTACH_NODE, &rd);
259092a3 246
6afc0dc3
GL
247 return 0;
248}
249
d8c50088 250void __of_detach_node(struct device_node *np)
6afc0dc3
GL
251{
252 struct device_node *parent;
6afc0dc3 253
d8c50088
PA
254 if (WARN_ON(of_node_check_flag(np, OF_DETACHED)))
255 return;
6afc0dc3
GL
256
257 parent = np->parent;
d8c50088
PA
258 if (WARN_ON(!parent))
259 return;
6afc0dc3 260
6afc0dc3
GL
261 if (parent->child == np)
262 parent->child = np->sibling;
263 else {
264 struct device_node *prevsib;
265 for (prevsib = np->parent->child;
266 prevsib->sibling != np;
267 prevsib = prevsib->sibling)
268 ;
269 prevsib->sibling = np->sibling;
270 }
271
272 of_node_set_flag(np, OF_DETACHED);
5801169a
FR
273
274 /* race with of_find_node_by_phandle() prevented by devtree_lock */
90dc0d1c 275 __of_phandle_cache_inv_entry(np->phandle);
d8c50088
PA
276}
277
278/**
279 * of_detach_node() - "Unplug" a node from the device tree.
3cb025d9 280 * @np: Pointer to the caller's Device Node
d8c50088
PA
281 */
282int of_detach_node(struct device_node *np)
283{
f5242e5a 284 struct of_reconfig_data rd;
d8c50088 285 unsigned long flags;
d8c50088 286
f5242e5a
GL
287 memset(&rd, 0, sizeof(rd));
288 rd.dn = np;
289
8a2b22a2 290 mutex_lock(&of_mutex);
d8c50088
PA
291 raw_spin_lock_irqsave(&devtree_lock, flags);
292 __of_detach_node(np);
6afc0dc3
GL
293 raw_spin_unlock_irqrestore(&devtree_lock, flags);
294
8a2b22a2
GL
295 __of_detach_node_sysfs(np);
296 mutex_unlock(&of_mutex);
259092a3 297
f5242e5a 298 of_reconfig_notify(OF_RECONFIG_DETACH_NODE, &rd);
259092a3 299
58fb82cc 300 return 0;
6afc0dc3 301}
bb91f923 302EXPORT_SYMBOL_GPL(of_detach_node);
6afc0dc3 303
070ea018
LW
304static void property_list_free(struct property *prop_list)
305{
306 struct property *prop, *next;
307
308 for (prop = prop_list; prop != NULL; prop = next) {
309 next = prop->next;
310 kfree(prop->name);
311 kfree(prop->value);
312 kfree(prop);
313 }
314}
315
6afc0dc3
GL
316/**
317 * of_node_release() - release a dynamically allocated node
3cb025d9 318 * @kobj: kernel object of the node to be released
6afc0dc3
GL
319 *
320 * In of_node_put() this function is passed to kref_put() as the destructor.
321 */
322void of_node_release(struct kobject *kobj)
323{
324 struct device_node *node = kobj_to_device_node(kobj);
6afc0dc3 325
23522dd7
FR
326 /*
327 * can not use '"%pOF", node' in pr_err() calls from this function
328 * because an of_node_get(node) when refcount is already zero
329 * will result in an error and a stack dump
330 */
331
6afc0dc3
GL
332 /* We should never be releasing nodes that haven't been detached. */
333 if (!of_node_check_flag(node, OF_DETACHED)) {
23522dd7
FR
334
335 pr_err("ERROR: %s() detected bad of_node_put() on %pOF/%s\n",
336 __func__, node->parent, node->full_name);
74df14cd
FR
337
338 /*
339 * of unittests will test this path. Do not print the stack
340 * trace when the error is caused by unittest so that we do
341 * not display what a normal developer might reasonably
342 * consider a real bug.
343 */
344 if (!IS_ENABLED(CONFIG_OF_UNITTEST) ||
345 strcmp(node->parent->full_name, "testcase-data")) {
346 dump_stack();
b4858dc6 347 pr_err("ERROR: next of_node_put() on this node will result in a kobject warning 'refcount_t: underflow; use-after-free.'\n");
74df14cd
FR
348 }
349
6afc0dc3
GL
350 return;
351 }
6afc0dc3
GL
352 if (!of_node_check_flag(node, OF_DYNAMIC))
353 return;
354
144552c7
FR
355 if (of_node_check_flag(node, OF_OVERLAY)) {
356
357 if (!of_node_check_flag(node, OF_OVERLAY_FREE_CSET)) {
358 /* premature refcount of zero, do not free memory */
359 pr_err("ERROR: memory leak before free overlay changeset, %pOF\n",
360 node);
361 return;
362 }
363
364 /*
365 * If node->properties non-empty then properties were added
366 * to this node either by different overlay that has not
367 * yet been removed, or by a non-overlay mechanism.
368 */
369 if (node->properties)
370 pr_err("ERROR: %s(), unexpected properties in %pOF\n",
371 __func__, node);
372 }
373
ec0b7e24
FR
374 if (node->child)
375 pr_err("ERROR: %s() unexpected children for %pOF/%s\n",
376 __func__, node->parent, node->full_name);
377
070ea018
LW
378 property_list_free(node->properties);
379 property_list_free(node->deadprops);
7b337cb3 380 fwnode_links_purge(of_fwnode_handle(node));
6afc0dc3 381
6afc0dc3
GL
382 kfree(node->full_name);
383 kfree(node->data);
384 kfree(node);
385}
69843396
PA
386
387/**
388 * __of_prop_dup - Copy a property dynamically.
389 * @prop: Property to copy
390 * @allocflags: Allocation flags (typically pass GFP_KERNEL)
391 *
392 * Copy a property by dynamically allocating the memory of both the
27b3383a 393 * property structure and the property name & contents. The property's
69843396
PA
394 * flags have the OF_DYNAMIC bit set so that we can differentiate between
395 * dynamically allocated properties and not.
8c8239c2
RH
396 *
397 * Return: The newly allocated property or NULL on out of memory error.
69843396
PA
398 */
399struct property *__of_prop_dup(const struct property *prop, gfp_t allocflags)
400{
401 struct property *new;
402
403 new = kzalloc(sizeof(*new), allocflags);
404 if (!new)
405 return NULL;
406
407 /*
408 * NOTE: There is no check for zero length value.
b6ae5dc5 409 * In case of a boolean property, this will allocate a value
69843396
PA
410 * of zero bytes. We do this to work around the use
411 * of of_get_property() calls on boolean values.
412 */
413 new->name = kstrdup(prop->name, allocflags);
414 new->value = kmemdup(prop->value, prop->length, allocflags);
415 new->length = prop->length;
416 if (!new->name || !new->value)
417 goto err_free;
418
419 /* mark the property as dynamic */
420 of_property_set_flag(new, OF_DYNAMIC);
421
422 return new;
423
424 err_free:
425 kfree(new->name);
426 kfree(new->value);
427 kfree(new);
428 return NULL;
429}
430
431/**
e5179581 432 * __of_node_dup() - Duplicate or create an empty device node dynamically.
b89dae18
FR
433 * @np: if not NULL, contains properties to be duplicated in new node
434 * @full_name: string value to be duplicated into new node's full_name field
69843396 435 *
b89dae18
FR
436 * Create a device tree node, optionally duplicating the properties of
437 * another node. The node data are dynamically allocated and all the node
438 * flags have the OF_DYNAMIC & OF_DETACHED bits set.
439 *
d9194e00
FR
440 * Return: The newly allocated node or NULL on out of memory error. Use
441 * of_node_put() on it when done to free the memory allocated for it.
69843396 442 */
b89dae18
FR
443struct device_node *__of_node_dup(const struct device_node *np,
444 const char *full_name)
69843396
PA
445{
446 struct device_node *node;
447
ef8bbd73 448 node = kzalloc(sizeof(*node), GFP_KERNEL);
69843396
PA
449 if (!node)
450 return NULL;
b89dae18 451 node->full_name = kstrdup(full_name, GFP_KERNEL);
e5179581
GL
452 if (!node->full_name) {
453 kfree(node);
454 return NULL;
455 }
69843396 456
ef8bbd73
GL
457 of_node_set_flag(node, OF_DYNAMIC);
458 of_node_set_flag(node, OF_DETACHED);
69843396
PA
459 of_node_init(node);
460
e5179581
GL
461 /* Iterate over and duplicate all properties */
462 if (np) {
463 struct property *pp, *new_pp;
464 for_each_property_of_node(np, pp) {
465 new_pp = __of_prop_dup(pp, GFP_KERNEL);
466 if (!new_pp)
467 goto err_prop;
468 if (__of_add_property(node, new_pp)) {
469 kfree(new_pp->name);
470 kfree(new_pp->value);
471 kfree(new_pp);
472 goto err_prop;
473 }
474 }
475 }
69843396
PA
476 return node;
477
e5179581
GL
478 err_prop:
479 of_node_put(node); /* Frees the node and properties */
69843396
PA
480 return NULL;
481}
201c910b
PA
482
483static void __of_changeset_entry_destroy(struct of_changeset_entry *ce)
484{
144552c7
FR
485 if (ce->action == OF_RECONFIG_ATTACH_NODE &&
486 of_node_check_flag(ce->np, OF_OVERLAY)) {
487 if (kref_read(&ce->np->kobj.kref) > 1) {
488 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",
489 kref_read(&ce->np->kobj.kref), ce->np);
490 } else {
491 of_node_set_flag(ce->np, OF_OVERLAY_FREE_CSET);
492 }
493 }
494
201c910b
PA
495 of_node_put(ce->np);
496 list_del(&ce->node);
497 kfree(ce);
498}
499
201c910b
PA
500static void __of_changeset_entry_invert(struct of_changeset_entry *ce,
501 struct of_changeset_entry *rce)
502{
503 memcpy(rce, ce, sizeof(*rce));
504
505 switch (ce->action) {
506 case OF_RECONFIG_ATTACH_NODE:
507 rce->action = OF_RECONFIG_DETACH_NODE;
508 break;
509 case OF_RECONFIG_DETACH_NODE:
510 rce->action = OF_RECONFIG_ATTACH_NODE;
511 break;
512 case OF_RECONFIG_ADD_PROPERTY:
513 rce->action = OF_RECONFIG_REMOVE_PROPERTY;
514 break;
515 case OF_RECONFIG_REMOVE_PROPERTY:
516 rce->action = OF_RECONFIG_ADD_PROPERTY;
517 break;
518 case OF_RECONFIG_UPDATE_PROPERTY:
519 rce->old_prop = ce->prop;
520 rce->prop = ce->old_prop;
b9c43856
PA
521 /* update was used but original property did not exist */
522 if (!rce->prop) {
523 rce->action = OF_RECONFIG_REMOVE_PROPERTY;
524 rce->prop = ce->prop;
525 }
201c910b
PA
526 break;
527 }
528}
529
24789c5c
FR
530static int __of_changeset_entry_notify(struct of_changeset_entry *ce,
531 bool revert)
201c910b 532{
f5242e5a 533 struct of_reconfig_data rd;
201c910b 534 struct of_changeset_entry ce_inverted;
24789c5c 535 int ret = 0;
201c910b
PA
536
537 if (revert) {
538 __of_changeset_entry_invert(ce, &ce_inverted);
539 ce = &ce_inverted;
540 }
541
542 switch (ce->action) {
543 case OF_RECONFIG_ATTACH_NODE:
544 case OF_RECONFIG_DETACH_NODE:
f5242e5a
GL
545 memset(&rd, 0, sizeof(rd));
546 rd.dn = ce->np;
547 ret = of_reconfig_notify(ce->action, &rd);
201c910b
PA
548 break;
549 case OF_RECONFIG_ADD_PROPERTY:
550 case OF_RECONFIG_REMOVE_PROPERTY:
551 case OF_RECONFIG_UPDATE_PROPERTY:
552 ret = of_property_notify(ce->action, ce->np, ce->prop, ce->old_prop);
553 break;
554 default:
606ad42a 555 pr_err("invalid devicetree changeset action: %i\n",
201c910b 556 (int)ce->action);
24789c5c 557 ret = -EINVAL;
201c910b
PA
558 }
559
560 if (ret)
0d638a07 561 pr_err("changeset notifier error @%pOF\n", ce->np);
24789c5c 562 return ret;
201c910b
PA
563}
564
565static int __of_changeset_entry_apply(struct of_changeset_entry *ce)
566{
567 struct property *old_prop, **propp;
568 unsigned long flags;
569 int ret = 0;
570
27a02f26 571 of_changeset_action_debug("apply: ", ce->action, ce->np, ce->prop);
201c910b
PA
572
573 raw_spin_lock_irqsave(&devtree_lock, flags);
574 switch (ce->action) {
575 case OF_RECONFIG_ATTACH_NODE:
576 __of_attach_node(ce->np);
577 break;
578 case OF_RECONFIG_DETACH_NODE:
579 __of_detach_node(ce->np);
580 break;
581 case OF_RECONFIG_ADD_PROPERTY:
582 /* If the property is in deadprops then it must be removed */
583 for (propp = &ce->np->deadprops; *propp; propp = &(*propp)->next) {
584 if (*propp == ce->prop) {
585 *propp = ce->prop->next;
586 ce->prop->next = NULL;
587 break;
588 }
589 }
590
591 ret = __of_add_property(ce->np, ce->prop);
201c910b
PA
592 break;
593 case OF_RECONFIG_REMOVE_PROPERTY:
594 ret = __of_remove_property(ce->np, ce->prop);
201c910b
PA
595 break;
596
597 case OF_RECONFIG_UPDATE_PROPERTY:
598 /* If the property is in deadprops then it must be removed */
599 for (propp = &ce->np->deadprops; *propp; propp = &(*propp)->next) {
600 if (*propp == ce->prop) {
601 *propp = ce->prop->next;
602 ce->prop->next = NULL;
603 break;
604 }
605 }
606
607 ret = __of_update_property(ce->np, ce->prop, &old_prop);
201c910b
PA
608 break;
609 default:
610 ret = -EINVAL;
611 }
612 raw_spin_unlock_irqrestore(&devtree_lock, flags);
613
914d9d83 614 if (ret) {
27a02f26 615 of_changeset_action_err("apply failed: ", ce->action, ce->np, ce->prop);
201c910b 616 return ret;
914d9d83 617 }
201c910b
PA
618
619 switch (ce->action) {
620 case OF_RECONFIG_ATTACH_NODE:
621 __of_attach_node_sysfs(ce->np);
622 break;
623 case OF_RECONFIG_DETACH_NODE:
624 __of_detach_node_sysfs(ce->np);
625 break;
626 case OF_RECONFIG_ADD_PROPERTY:
627 /* ignore duplicate names */
628 __of_add_property_sysfs(ce->np, ce->prop);
629 break;
630 case OF_RECONFIG_REMOVE_PROPERTY:
631 __of_remove_property_sysfs(ce->np, ce->prop);
632 break;
633 case OF_RECONFIG_UPDATE_PROPERTY:
634 __of_update_property_sysfs(ce->np, ce->prop, ce->old_prop);
635 break;
636 }
637
638 return 0;
639}
640
641static inline int __of_changeset_entry_revert(struct of_changeset_entry *ce)
642{
643 struct of_changeset_entry ce_inverted;
644
645 __of_changeset_entry_invert(ce, &ce_inverted);
646 return __of_changeset_entry_apply(&ce_inverted);
647}
648
649/**
650 * of_changeset_init - Initialize a changeset for use
651 *
652 * @ocs: changeset pointer
653 *
654 * Initialize a changeset structure
655 */
656void of_changeset_init(struct of_changeset *ocs)
657{
658 memset(ocs, 0, sizeof(*ocs));
659 INIT_LIST_HEAD(&ocs->entries);
660}
18322377 661EXPORT_SYMBOL_GPL(of_changeset_init);
201c910b
PA
662
663/**
664 * of_changeset_destroy - Destroy a changeset
665 *
666 * @ocs: changeset pointer
667 *
668 * Destroys a changeset. Note that if a changeset is applied,
669 * its changes to the tree cannot be reverted.
670 */
671void of_changeset_destroy(struct of_changeset *ocs)
672{
673 struct of_changeset_entry *ce, *cen;
674
675 list_for_each_entry_safe_reverse(ce, cen, &ocs->entries, node)
676 __of_changeset_entry_destroy(ce);
677}
18322377 678EXPORT_SYMBOL_GPL(of_changeset_destroy);
201c910b 679
24789c5c
FR
680/*
681 * Apply the changeset entries in @ocs.
682 * If apply fails, an attempt is made to revert the entries that were
683 * successfully applied.
684 *
685 * If multiple revert errors occur then only the final revert error is reported.
686 *
687 * Returns 0 on success, a negative error value in case of an error.
688 * If a revert error occurs, it is returned in *ret_revert.
689 */
690int __of_changeset_apply_entries(struct of_changeset *ocs, int *ret_revert)
201c910b
PA
691{
692 struct of_changeset_entry *ce;
24789c5c 693 int ret, ret_tmp;
201c910b 694
606ad42a 695 pr_debug("changeset: applying...\n");
201c910b
PA
696 list_for_each_entry(ce, &ocs->entries, node) {
697 ret = __of_changeset_entry_apply(ce);
698 if (ret) {
606ad42a 699 pr_err("Error applying changeset (%d)\n", ret);
24789c5c
FR
700 list_for_each_entry_continue_reverse(ce, &ocs->entries,
701 node) {
702 ret_tmp = __of_changeset_entry_revert(ce);
703 if (ret_tmp)
704 *ret_revert = ret_tmp;
705 }
201c910b
PA
706 return ret;
707 }
708 }
24789c5c
FR
709
710 return 0;
711}
712
713/*
714 * Returns 0 on success, a negative error value in case of an error.
715 *
e9d92e40 716 * If multiple changeset entry notification errors occur then only the
24789c5c
FR
717 * final notification error is reported.
718 */
719int __of_changeset_apply_notify(struct of_changeset *ocs)
720{
721 struct of_changeset_entry *ce;
722 int ret = 0, ret_tmp;
723
724 pr_debug("changeset: emitting notifiers.\n");
201c910b
PA
725
726 /* drop the global lock while emitting notifiers */
727 mutex_unlock(&of_mutex);
24789c5c
FR
728 list_for_each_entry(ce, &ocs->entries, node) {
729 ret_tmp = __of_changeset_entry_notify(ce, 0);
730 if (ret_tmp)
731 ret = ret_tmp;
732 }
201c910b 733 mutex_lock(&of_mutex);
606ad42a 734 pr_debug("changeset: notifiers sent.\n");
201c910b 735
24789c5c
FR
736 return ret;
737}
738
739/*
740 * Returns 0 on success, a negative error value in case of an error.
741 *
742 * If a changeset entry apply fails, an attempt is made to revert any
743 * previous entries in the changeset. If any of the reverts fails,
744 * that failure is not reported. Thus the state of the device tree
745 * is unknown if an apply error occurs.
746 */
747static int __of_changeset_apply(struct of_changeset *ocs)
748{
749 int ret, ret_revert = 0;
750
751 ret = __of_changeset_apply_entries(ocs, &ret_revert);
752 if (!ret)
753 ret = __of_changeset_apply_notify(ocs);
754
755 return ret;
201c910b
PA
756}
757
758/**
18322377 759 * of_changeset_apply - Applies a changeset
201c910b
PA
760 *
761 * @ocs: changeset pointer
762 *
18322377
GS
763 * Applies a changeset to the live tree.
764 * Any side-effects of live tree state changes are applied here on
765 * success, like creation/destruction of devices and side-effects
766 * like creation of sysfs properties and directories.
8c8239c2
RH
767 *
768 * Return: 0 on success, a negative error value in case of an error.
18322377 769 * On error the partially applied effects are reverted.
201c910b 770 */
18322377
GS
771int of_changeset_apply(struct of_changeset *ocs)
772{
773 int ret;
774
775 mutex_lock(&of_mutex);
776 ret = __of_changeset_apply(ocs);
777 mutex_unlock(&of_mutex);
778
779 return ret;
780}
781EXPORT_SYMBOL_GPL(of_changeset_apply);
782
24789c5c
FR
783/*
784 * Revert the changeset entries in @ocs.
785 * If revert fails, an attempt is made to re-apply the entries that were
786 * successfully removed.
787 *
788 * If multiple re-apply errors occur then only the final apply error is
789 * reported.
790 *
791 * Returns 0 on success, a negative error value in case of an error.
792 * If an apply error occurs, it is returned in *ret_apply.
793 */
794int __of_changeset_revert_entries(struct of_changeset *ocs, int *ret_apply)
201c910b
PA
795{
796 struct of_changeset_entry *ce;
24789c5c 797 int ret, ret_tmp;
201c910b 798
606ad42a 799 pr_debug("changeset: reverting...\n");
201c910b
PA
800 list_for_each_entry_reverse(ce, &ocs->entries, node) {
801 ret = __of_changeset_entry_revert(ce);
802 if (ret) {
606ad42a 803 pr_err("Error reverting changeset (%d)\n", ret);
24789c5c
FR
804 list_for_each_entry_continue(ce, &ocs->entries, node) {
805 ret_tmp = __of_changeset_entry_apply(ce);
806 if (ret_tmp)
807 *ret_apply = ret_tmp;
808 }
201c910b
PA
809 return ret;
810 }
811 }
24789c5c
FR
812
813 return 0;
814}
815
816/*
e9d92e40 817 * If multiple changeset entry notification errors occur then only the
24789c5c
FR
818 * final notification error is reported.
819 */
820int __of_changeset_revert_notify(struct of_changeset *ocs)
821{
822 struct of_changeset_entry *ce;
823 int ret = 0, ret_tmp;
824
825 pr_debug("changeset: emitting notifiers.\n");
201c910b
PA
826
827 /* drop the global lock while emitting notifiers */
828 mutex_unlock(&of_mutex);
24789c5c
FR
829 list_for_each_entry_reverse(ce, &ocs->entries, node) {
830 ret_tmp = __of_changeset_entry_notify(ce, 1);
831 if (ret_tmp)
832 ret = ret_tmp;
833 }
201c910b 834 mutex_lock(&of_mutex);
606ad42a 835 pr_debug("changeset: notifiers sent.\n");
201c910b 836
24789c5c
FR
837 return ret;
838}
839
840static int __of_changeset_revert(struct of_changeset *ocs)
841{
842 int ret, ret_reply;
843
844 ret_reply = 0;
845 ret = __of_changeset_revert_entries(ocs, &ret_reply);
846
847 if (!ret)
848 ret = __of_changeset_revert_notify(ocs);
849
850 return ret;
201c910b
PA
851}
852
18322377
GS
853/**
854 * of_changeset_revert - Reverts an applied changeset
855 *
856 * @ocs: changeset pointer
857 *
858 * Reverts a changeset returning the state of the tree to what it
859 * was before the application.
860 * Any side-effects like creation/destruction of devices and
861 * removal of sysfs properties and directories are applied.
8c8239c2
RH
862 *
863 * Return: 0 on success, a negative error value in case of an error.
18322377
GS
864 */
865int of_changeset_revert(struct of_changeset *ocs)
866{
867 int ret;
868
869 mutex_lock(&of_mutex);
870 ret = __of_changeset_revert(ocs);
871 mutex_unlock(&of_mutex);
872
873 return ret;
874}
875EXPORT_SYMBOL_GPL(of_changeset_revert);
876
201c910b 877/**
0290c4ca 878 * of_changeset_action - Add an action to the tail of the changeset list
201c910b
PA
879 *
880 * @ocs: changeset pointer
881 * @action: action to perform
882 * @np: Pointer to device node
883 * @prop: Pointer to property
884 *
885 * On action being one of:
886 * + OF_RECONFIG_ATTACH_NODE
887 * + OF_RECONFIG_DETACH_NODE,
888 * + OF_RECONFIG_ADD_PROPERTY
889 * + OF_RECONFIG_REMOVE_PROPERTY,
890 * + OF_RECONFIG_UPDATE_PROPERTY
8c8239c2
RH
891 *
892 * Return: 0 on success, a negative error value in case of an error.
201c910b
PA
893 */
894int of_changeset_action(struct of_changeset *ocs, unsigned long action,
895 struct device_node *np, struct property *prop)
896{
897 struct of_changeset_entry *ce;
898
899 ce = kzalloc(sizeof(*ce), GFP_KERNEL);
606ad42a 900 if (!ce)
201c910b 901 return -ENOMEM;
606ad42a 902
914d9d83
RH
903 if (WARN_ON(action >= ARRAY_SIZE(action_names)))
904 return -EINVAL;
905
201c910b
PA
906 /* get a reference to the node */
907 ce->action = action;
908 ce->np = of_node_get(np);
909 ce->prop = prop;
910
911 if (action == OF_RECONFIG_UPDATE_PROPERTY && prop)
912 ce->old_prop = of_find_property(np, prop->name, NULL);
913
914 /* add it to the list */
915 list_add_tail(&ce->node, &ocs->entries);
916 return 0;
917}
18322377 918EXPORT_SYMBOL_GPL(of_changeset_action);
This page took 0.643318 seconds and 4 git commands to generate.