blob: cc106529dca8eef016aab48ce3c92deb6eb9fca7 [file] [log] [blame]
Grant Likely6afc0dc2014-06-26 15:40:48 +01001/*
2 * Support for dynamic device trees.
3 *
4 * On some platforms, the device tree can be manipulated at runtime.
5 * The routines in this section support adding, removing and changing
6 * device tree nodes.
7 */
8
9#include <linux/of.h>
10#include <linux/spinlock.h>
11#include <linux/slab.h>
12#include <linux/string.h>
13#include <linux/proc_fs.h>
14
15#include "of_private.h"
16
17/**
18 * of_node_get() - Increment refcount of a node
19 * @node: Node to inc refcount, NULL is supported to simplify writing of
20 * callers
21 *
22 * Returns node.
23 */
24struct device_node *of_node_get(struct device_node *node)
25{
26 if (node)
27 kobject_get(&node->kobj);
28 return node;
29}
30EXPORT_SYMBOL(of_node_get);
31
32/**
33 * of_node_put() - Decrement refcount of a node
34 * @node: Node to dec refcount, NULL is supported to simplify writing of
35 * callers
36 */
37void of_node_put(struct device_node *node)
38{
39 if (node)
40 kobject_put(&node->kobj);
41}
42EXPORT_SYMBOL(of_node_put);
43
Grant Likely8a2b22a2014-07-23 17:05:06 -060044void __of_detach_node_sysfs(struct device_node *np)
Grant Likely6afc0dc2014-06-26 15:40:48 +010045{
46 struct property *pp;
47
Gaurav Minochaef69d742014-09-05 09:56:13 -070048 if (!IS_ENABLED(CONFIG_SYSFS))
49 return;
50
Grant Likely6afc0dc2014-06-26 15:40:48 +010051 BUG_ON(!of_node_is_initialized(np));
Grant Likely8a2b22a2014-07-23 17:05:06 -060052 if (!of_kset)
53 return;
Grant Likely6afc0dc2014-06-26 15:40:48 +010054
55 /* only remove properties if on sysfs */
56 if (of_node_is_attached(np)) {
57 for_each_property_of_node(np, pp)
58 sysfs_remove_bin_file(&np->kobj, &pp->attr);
59 kobject_del(&np->kobj);
60 }
61
62 /* finally remove the kobj_init ref */
63 of_node_put(np);
64}
65
66static BLOCKING_NOTIFIER_HEAD(of_reconfig_chain);
67
68int of_reconfig_notifier_register(struct notifier_block *nb)
69{
70 return blocking_notifier_chain_register(&of_reconfig_chain, nb);
71}
72EXPORT_SYMBOL_GPL(of_reconfig_notifier_register);
73
74int of_reconfig_notifier_unregister(struct notifier_block *nb)
75{
76 return blocking_notifier_chain_unregister(&of_reconfig_chain, nb);
77}
78EXPORT_SYMBOL_GPL(of_reconfig_notifier_unregister);
79
Grant Likely00aa3722014-11-14 14:34:55 +000080#ifdef DEBUG
81const char *action_names[] = {
82 [OF_RECONFIG_ATTACH_NODE] = "ATTACH_NODE",
83 [OF_RECONFIG_DETACH_NODE] = "DETACH_NODE",
84 [OF_RECONFIG_ADD_PROPERTY] = "ADD_PROPERTY",
85 [OF_RECONFIG_REMOVE_PROPERTY] = "REMOVE_PROPERTY",
86 [OF_RECONFIG_UPDATE_PROPERTY] = "UPDATE_PROPERTY",
87};
88#endif
89
Grant Likely6afc0dc2014-06-26 15:40:48 +010090int of_reconfig_notify(unsigned long action, void *p)
91{
92 int rc;
Grant Likely00aa3722014-11-14 14:34:55 +000093#ifdef DEBUG
94 struct device_node *dn = p;
95 struct of_prop_reconfig *pr = p;
Grant Likely6afc0dc2014-06-26 15:40:48 +010096
Grant Likely00aa3722014-11-14 14:34:55 +000097 switch (action) {
98 case OF_RECONFIG_ATTACH_NODE:
99 case OF_RECONFIG_DETACH_NODE:
100 pr_debug("of/notify %-15s %s\n", action_names[action],
101 dn->full_name);
102 break;
103 case OF_RECONFIG_ADD_PROPERTY:
104 case OF_RECONFIG_REMOVE_PROPERTY:
105 case OF_RECONFIG_UPDATE_PROPERTY:
106 pr_debug("of/notify %-15s %s:%s\n", action_names[action],
107 pr->dn->full_name, pr->prop->name);
108 break;
109
110 }
111#endif
Grant Likely6afc0dc2014-06-26 15:40:48 +0100112 rc = blocking_notifier_call_chain(&of_reconfig_chain, action, p);
113 return notifier_to_errno(rc);
114}
115
Pantelis Antonioub53a2342014-10-28 22:33:53 +0200116/*
117 * of_reconfig_get_state_change() - Returns new state of device
118 * @action - action of the of notifier
119 * @arg - argument of the of notifier
120 *
121 * Returns the new state of a device based on the notifier used.
122 * Returns 0 on device going from enabled to disabled, 1 on device
123 * going from disabled to enabled and -1 on no change.
124 */
125int of_reconfig_get_state_change(unsigned long action, void *arg)
126{
127 struct device_node *dn;
128 struct property *prop, *old_prop;
129 struct of_prop_reconfig *pr;
130 int is_status, status_state, old_status_state, prev_state, new_state;
131
132 /* figure out if a device should be created or destroyed */
133 dn = NULL;
134 prop = old_prop = NULL;
135 switch (action) {
136 case OF_RECONFIG_ATTACH_NODE:
137 case OF_RECONFIG_DETACH_NODE:
138 dn = arg;
139 prop = of_find_property(dn, "status", NULL);
140 break;
141 case OF_RECONFIG_ADD_PROPERTY:
142 case OF_RECONFIG_REMOVE_PROPERTY:
143 pr = arg;
144 dn = pr->dn;
145 prop = pr->prop;
146 break;
147 case OF_RECONFIG_UPDATE_PROPERTY:
148 pr = arg;
149 dn = pr->dn;
150 prop = pr->prop;
151 old_prop = pr->old_prop;
152 break;
153 default:
154 return OF_RECONFIG_NO_CHANGE;
155 }
156
157 is_status = 0;
158 status_state = -1;
159 old_status_state = -1;
160 prev_state = -1;
161 new_state = -1;
162
163 if (prop && !strcmp(prop->name, "status")) {
164 is_status = 1;
165 status_state = !strcmp(prop->value, "okay") ||
166 !strcmp(prop->value, "ok");
167 if (old_prop)
168 old_status_state = !strcmp(old_prop->value, "okay") ||
169 !strcmp(old_prop->value, "ok");
170 }
171
172 switch (action) {
173 case OF_RECONFIG_ATTACH_NODE:
174 prev_state = 0;
175 /* -1 & 0 status either missing or okay */
176 new_state = status_state != 0;
177 break;
178 case OF_RECONFIG_DETACH_NODE:
179 /* -1 & 0 status either missing or okay */
180 prev_state = status_state != 0;
181 new_state = 0;
182 break;
183 case OF_RECONFIG_ADD_PROPERTY:
184 if (is_status) {
185 /* no status property -> enabled (legacy) */
186 prev_state = 1;
187 new_state = status_state;
188 }
189 break;
190 case OF_RECONFIG_REMOVE_PROPERTY:
191 if (is_status) {
192 prev_state = status_state;
193 /* no status property -> enabled (legacy) */
194 new_state = 1;
195 }
196 break;
197 case OF_RECONFIG_UPDATE_PROPERTY:
198 if (is_status) {
199 prev_state = old_status_state != 0;
200 new_state = status_state != 0;
201 }
202 break;
203 }
204
205 if (prev_state == new_state)
206 return OF_RECONFIG_NO_CHANGE;
207
208 return new_state ? OF_RECONFIG_CHANGE_ADD : OF_RECONFIG_CHANGE_REMOVE;
209}
210EXPORT_SYMBOL_GPL(of_reconfig_get_state_change);
211
Grant Likely6afc0dc2014-06-26 15:40:48 +0100212int of_property_notify(int action, struct device_node *np,
Grant Likely259092a2014-07-16 12:48:23 -0600213 struct property *prop, struct property *oldprop)
Grant Likely6afc0dc2014-06-26 15:40:48 +0100214{
215 struct of_prop_reconfig pr;
216
217 /* only call notifiers if the node is attached */
218 if (!of_node_is_attached(np))
219 return 0;
220
221 pr.dn = np;
222 pr.prop = prop;
Grant Likely259092a2014-07-16 12:48:23 -0600223 pr.old_prop = oldprop;
Grant Likely6afc0dc2014-06-26 15:40:48 +0100224 return of_reconfig_notify(action, &pr);
225}
226
Pantelis Antonioud8c50082014-07-04 19:58:46 +0300227void __of_attach_node(struct device_node *np)
228{
Grant Likelya25095d2014-07-15 23:25:43 -0600229 const __be32 *phandle;
230 int sz;
231
232 np->name = __of_get_property(np, "name", NULL) ? : "<NULL>";
233 np->type = __of_get_property(np, "device_type", NULL) ? : "<NULL>";
234
235 phandle = __of_get_property(np, "phandle", &sz);
236 if (!phandle)
237 phandle = __of_get_property(np, "linux,phandle", &sz);
238 if (IS_ENABLED(PPC_PSERIES) && !phandle)
239 phandle = __of_get_property(np, "ibm,phandle", &sz);
240 np->phandle = (phandle && (sz >= 4)) ? be32_to_cpup(phandle) : 0;
241
Grant Likely6162dbe2014-07-16 08:48:46 -0600242 np->child = NULL;
Pantelis Antonioud8c50082014-07-04 19:58:46 +0300243 np->sibling = np->parent->child;
Pantelis Antonioud8c50082014-07-04 19:58:46 +0300244 np->parent->child = np;
245 of_node_clear_flag(np, OF_DETACHED);
246}
247
Grant Likely6afc0dc2014-06-26 15:40:48 +0100248/**
249 * of_attach_node() - Plug a device node into the tree and global list.
250 */
251int of_attach_node(struct device_node *np)
252{
253 unsigned long flags;
Grant Likely6afc0dc2014-06-26 15:40:48 +0100254
Grant Likely8a2b22a2014-07-23 17:05:06 -0600255 mutex_lock(&of_mutex);
Grant Likely6afc0dc2014-06-26 15:40:48 +0100256 raw_spin_lock_irqsave(&devtree_lock, flags);
Pantelis Antonioud8c50082014-07-04 19:58:46 +0300257 __of_attach_node(np);
Grant Likely6afc0dc2014-06-26 15:40:48 +0100258 raw_spin_unlock_irqrestore(&devtree_lock, flags);
259
Grant Likely8a2b22a2014-07-23 17:05:06 -0600260 __of_attach_node_sysfs(np);
261 mutex_unlock(&of_mutex);
Grant Likely259092a2014-07-16 12:48:23 -0600262
263 of_reconfig_notify(OF_RECONFIG_ATTACH_NODE, np);
264
Grant Likely6afc0dc2014-06-26 15:40:48 +0100265 return 0;
266}
267
Pantelis Antonioud8c50082014-07-04 19:58:46 +0300268void __of_detach_node(struct device_node *np)
Grant Likely6afc0dc2014-06-26 15:40:48 +0100269{
270 struct device_node *parent;
Grant Likely6afc0dc2014-06-26 15:40:48 +0100271
Pantelis Antonioud8c50082014-07-04 19:58:46 +0300272 if (WARN_ON(of_node_check_flag(np, OF_DETACHED)))
273 return;
Grant Likely6afc0dc2014-06-26 15:40:48 +0100274
275 parent = np->parent;
Pantelis Antonioud8c50082014-07-04 19:58:46 +0300276 if (WARN_ON(!parent))
277 return;
Grant Likely6afc0dc2014-06-26 15:40:48 +0100278
Grant Likely6afc0dc2014-06-26 15:40:48 +0100279 if (parent->child == np)
280 parent->child = np->sibling;
281 else {
282 struct device_node *prevsib;
283 for (prevsib = np->parent->child;
284 prevsib->sibling != np;
285 prevsib = prevsib->sibling)
286 ;
287 prevsib->sibling = np->sibling;
288 }
289
290 of_node_set_flag(np, OF_DETACHED);
Pantelis Antonioud8c50082014-07-04 19:58:46 +0300291}
292
293/**
294 * of_detach_node() - "Unplug" a node from the device tree.
295 *
296 * The caller must hold a reference to the node. The memory associated with
297 * the node is not freed until its refcount goes to zero.
298 */
299int of_detach_node(struct device_node *np)
300{
301 unsigned long flags;
302 int rc = 0;
303
Grant Likely8a2b22a2014-07-23 17:05:06 -0600304 mutex_lock(&of_mutex);
Pantelis Antonioud8c50082014-07-04 19:58:46 +0300305 raw_spin_lock_irqsave(&devtree_lock, flags);
306 __of_detach_node(np);
Grant Likely6afc0dc2014-06-26 15:40:48 +0100307 raw_spin_unlock_irqrestore(&devtree_lock, flags);
308
Grant Likely8a2b22a2014-07-23 17:05:06 -0600309 __of_detach_node_sysfs(np);
310 mutex_unlock(&of_mutex);
Grant Likely259092a2014-07-16 12:48:23 -0600311
312 of_reconfig_notify(OF_RECONFIG_DETACH_NODE, np);
313
Grant Likely6afc0dc2014-06-26 15:40:48 +0100314 return rc;
315}
316
317/**
318 * of_node_release() - release a dynamically allocated node
319 * @kref: kref element of the node to be released
320 *
321 * In of_node_put() this function is passed to kref_put() as the destructor.
322 */
323void of_node_release(struct kobject *kobj)
324{
325 struct device_node *node = kobj_to_device_node(kobj);
326 struct property *prop = node->properties;
327
328 /* We should never be releasing nodes that haven't been detached. */
329 if (!of_node_check_flag(node, OF_DETACHED)) {
330 pr_err("ERROR: Bad of_node_put() on %s\n", node->full_name);
331 dump_stack();
332 return;
333 }
334
335 if (!of_node_check_flag(node, OF_DYNAMIC))
336 return;
337
338 while (prop) {
339 struct property *next = prop->next;
340 kfree(prop->name);
341 kfree(prop->value);
342 kfree(prop);
343 prop = next;
344
345 if (!prop) {
346 prop = node->deadprops;
347 node->deadprops = NULL;
348 }
349 }
350 kfree(node->full_name);
351 kfree(node->data);
352 kfree(node);
353}
Pantelis Antoniou69843392014-07-04 19:58:47 +0300354
355/**
356 * __of_prop_dup - Copy a property dynamically.
357 * @prop: Property to copy
358 * @allocflags: Allocation flags (typically pass GFP_KERNEL)
359 *
360 * Copy a property by dynamically allocating the memory of both the
Geert Uytterhoeven27b33832014-10-22 11:49:01 +0200361 * property structure and the property name & contents. The property's
Pantelis Antoniou69843392014-07-04 19:58:47 +0300362 * flags have the OF_DYNAMIC bit set so that we can differentiate between
363 * dynamically allocated properties and not.
364 * Returns the newly allocated property or NULL on out of memory error.
365 */
366struct property *__of_prop_dup(const struct property *prop, gfp_t allocflags)
367{
368 struct property *new;
369
370 new = kzalloc(sizeof(*new), allocflags);
371 if (!new)
372 return NULL;
373
374 /*
375 * NOTE: There is no check for zero length value.
Grant Likelyb6ae5dc2014-07-26 10:58:43 -0600376 * In case of a boolean property, this will allocate a value
Pantelis Antoniou69843392014-07-04 19:58:47 +0300377 * of zero bytes. We do this to work around the use
378 * of of_get_property() calls on boolean values.
379 */
380 new->name = kstrdup(prop->name, allocflags);
381 new->value = kmemdup(prop->value, prop->length, allocflags);
382 new->length = prop->length;
383 if (!new->name || !new->value)
384 goto err_free;
385
386 /* mark the property as dynamic */
387 of_property_set_flag(new, OF_DYNAMIC);
388
389 return new;
390
391 err_free:
392 kfree(new->name);
393 kfree(new->value);
394 kfree(new);
395 return NULL;
396}
397
398/**
Grant Likelye5179582014-11-17 22:31:32 +0000399 * __of_node_dup() - Duplicate or create an empty device node dynamically.
400 * @fmt: Format string (plus vargs) for new full name of the device node
Pantelis Antoniou69843392014-07-04 19:58:47 +0300401 *
Grant Likelye5179582014-11-17 22:31:32 +0000402 * Create an device tree node, either by duplicating an empty node or by allocating
403 * an empty one suitable for further modification. The node data are
404 * dynamically allocated and all the node flags have the OF_DYNAMIC &
405 * OF_DETACHED bits set. Returns the newly allocated node or NULL on out of
406 * memory error.
Pantelis Antoniou69843392014-07-04 19:58:47 +0300407 */
Grant Likelye5179582014-11-17 22:31:32 +0000408struct device_node *__of_node_dup(const struct device_node *np, const char *fmt, ...)
Pantelis Antoniou69843392014-07-04 19:58:47 +0300409{
Grant Likelyef8bbd72014-11-14 15:33:07 +0000410 va_list vargs;
Pantelis Antoniou69843392014-07-04 19:58:47 +0300411 struct device_node *node;
412
Grant Likelyef8bbd72014-11-14 15:33:07 +0000413 node = kzalloc(sizeof(*node), GFP_KERNEL);
Pantelis Antoniou69843392014-07-04 19:58:47 +0300414 if (!node)
415 return NULL;
Grant Likelyef8bbd72014-11-14 15:33:07 +0000416 va_start(vargs, fmt);
417 node->full_name = kvasprintf(GFP_KERNEL, fmt, vargs);
418 va_end(vargs);
Grant Likelye5179582014-11-17 22:31:32 +0000419 if (!node->full_name) {
420 kfree(node);
421 return NULL;
422 }
Pantelis Antoniou69843392014-07-04 19:58:47 +0300423
Grant Likelyef8bbd72014-11-14 15:33:07 +0000424 of_node_set_flag(node, OF_DYNAMIC);
425 of_node_set_flag(node, OF_DETACHED);
Pantelis Antoniou69843392014-07-04 19:58:47 +0300426 of_node_init(node);
427
Grant Likelye5179582014-11-17 22:31:32 +0000428 /* Iterate over and duplicate all properties */
429 if (np) {
430 struct property *pp, *new_pp;
431 for_each_property_of_node(np, pp) {
432 new_pp = __of_prop_dup(pp, GFP_KERNEL);
433 if (!new_pp)
434 goto err_prop;
435 if (__of_add_property(node, new_pp)) {
436 kfree(new_pp->name);
437 kfree(new_pp->value);
438 kfree(new_pp);
439 goto err_prop;
440 }
441 }
442 }
Pantelis Antoniou69843392014-07-04 19:58:47 +0300443 return node;
444
Grant Likelye5179582014-11-17 22:31:32 +0000445 err_prop:
446 of_node_put(node); /* Frees the node and properties */
Pantelis Antoniou69843392014-07-04 19:58:47 +0300447 return NULL;
448}
Pantelis Antoniou201c9102014-07-04 19:58:49 +0300449
450static void __of_changeset_entry_destroy(struct of_changeset_entry *ce)
451{
452 of_node_put(ce->np);
453 list_del(&ce->node);
454 kfree(ce);
455}
456
457#ifdef DEBUG
458static void __of_changeset_entry_dump(struct of_changeset_entry *ce)
459{
460 switch (ce->action) {
461 case OF_RECONFIG_ADD_PROPERTY:
Pantelis Antoniou201c9102014-07-04 19:58:49 +0300462 case OF_RECONFIG_REMOVE_PROPERTY:
Pantelis Antoniou201c9102014-07-04 19:58:49 +0300463 case OF_RECONFIG_UPDATE_PROPERTY:
Grant Likely00aa3722014-11-14 14:34:55 +0000464 pr_debug("of/cset<%p> %-15s %s/%s\n", ce, action_names[ce->action],
465 ce->np->full_name, ce->prop->name);
Pantelis Antoniou201c9102014-07-04 19:58:49 +0300466 break;
467 case OF_RECONFIG_ATTACH_NODE:
Pantelis Antoniou201c9102014-07-04 19:58:49 +0300468 case OF_RECONFIG_DETACH_NODE:
Grant Likely00aa3722014-11-14 14:34:55 +0000469 pr_debug("of/cset<%p> %-15s %s\n", ce, action_names[ce->action],
470 ce->np->full_name);
Pantelis Antoniou201c9102014-07-04 19:58:49 +0300471 break;
472 }
473}
474#else
475static inline void __of_changeset_entry_dump(struct of_changeset_entry *ce)
476{
477 /* empty */
478}
479#endif
480
481static void __of_changeset_entry_invert(struct of_changeset_entry *ce,
482 struct of_changeset_entry *rce)
483{
484 memcpy(rce, ce, sizeof(*rce));
485
486 switch (ce->action) {
487 case OF_RECONFIG_ATTACH_NODE:
488 rce->action = OF_RECONFIG_DETACH_NODE;
489 break;
490 case OF_RECONFIG_DETACH_NODE:
491 rce->action = OF_RECONFIG_ATTACH_NODE;
492 break;
493 case OF_RECONFIG_ADD_PROPERTY:
494 rce->action = OF_RECONFIG_REMOVE_PROPERTY;
495 break;
496 case OF_RECONFIG_REMOVE_PROPERTY:
497 rce->action = OF_RECONFIG_ADD_PROPERTY;
498 break;
499 case OF_RECONFIG_UPDATE_PROPERTY:
500 rce->old_prop = ce->prop;
501 rce->prop = ce->old_prop;
502 break;
503 }
504}
505
506static void __of_changeset_entry_notify(struct of_changeset_entry *ce, bool revert)
507{
508 struct of_changeset_entry ce_inverted;
509 int ret;
510
511 if (revert) {
512 __of_changeset_entry_invert(ce, &ce_inverted);
513 ce = &ce_inverted;
514 }
515
516 switch (ce->action) {
517 case OF_RECONFIG_ATTACH_NODE:
518 case OF_RECONFIG_DETACH_NODE:
519 ret = of_reconfig_notify(ce->action, ce->np);
520 break;
521 case OF_RECONFIG_ADD_PROPERTY:
522 case OF_RECONFIG_REMOVE_PROPERTY:
523 case OF_RECONFIG_UPDATE_PROPERTY:
524 ret = of_property_notify(ce->action, ce->np, ce->prop, ce->old_prop);
525 break;
526 default:
527 pr_err("%s: invalid devicetree changeset action: %i\n", __func__,
528 (int)ce->action);
529 return;
530 }
531
532 if (ret)
533 pr_err("%s: notifier error @%s\n", __func__, ce->np->full_name);
534}
535
536static int __of_changeset_entry_apply(struct of_changeset_entry *ce)
537{
538 struct property *old_prop, **propp;
539 unsigned long flags;
540 int ret = 0;
541
542 __of_changeset_entry_dump(ce);
543
544 raw_spin_lock_irqsave(&devtree_lock, flags);
545 switch (ce->action) {
546 case OF_RECONFIG_ATTACH_NODE:
547 __of_attach_node(ce->np);
548 break;
549 case OF_RECONFIG_DETACH_NODE:
550 __of_detach_node(ce->np);
551 break;
552 case OF_RECONFIG_ADD_PROPERTY:
553 /* If the property is in deadprops then it must be removed */
554 for (propp = &ce->np->deadprops; *propp; propp = &(*propp)->next) {
555 if (*propp == ce->prop) {
556 *propp = ce->prop->next;
557 ce->prop->next = NULL;
558 break;
559 }
560 }
561
562 ret = __of_add_property(ce->np, ce->prop);
563 if (ret) {
564 pr_err("%s: add_property failed @%s/%s\n",
565 __func__, ce->np->full_name,
566 ce->prop->name);
567 break;
568 }
569 break;
570 case OF_RECONFIG_REMOVE_PROPERTY:
571 ret = __of_remove_property(ce->np, ce->prop);
572 if (ret) {
573 pr_err("%s: remove_property failed @%s/%s\n",
574 __func__, ce->np->full_name,
575 ce->prop->name);
576 break;
577 }
578 break;
579
580 case OF_RECONFIG_UPDATE_PROPERTY:
581 /* If the property is in deadprops then it must be removed */
582 for (propp = &ce->np->deadprops; *propp; propp = &(*propp)->next) {
583 if (*propp == ce->prop) {
584 *propp = ce->prop->next;
585 ce->prop->next = NULL;
586 break;
587 }
588 }
589
590 ret = __of_update_property(ce->np, ce->prop, &old_prop);
591 if (ret) {
592 pr_err("%s: update_property failed @%s/%s\n",
593 __func__, ce->np->full_name,
594 ce->prop->name);
595 break;
596 }
597 break;
598 default:
599 ret = -EINVAL;
600 }
601 raw_spin_unlock_irqrestore(&devtree_lock, flags);
602
603 if (ret)
604 return ret;
605
606 switch (ce->action) {
607 case OF_RECONFIG_ATTACH_NODE:
608 __of_attach_node_sysfs(ce->np);
609 break;
610 case OF_RECONFIG_DETACH_NODE:
611 __of_detach_node_sysfs(ce->np);
612 break;
613 case OF_RECONFIG_ADD_PROPERTY:
614 /* ignore duplicate names */
615 __of_add_property_sysfs(ce->np, ce->prop);
616 break;
617 case OF_RECONFIG_REMOVE_PROPERTY:
618 __of_remove_property_sysfs(ce->np, ce->prop);
619 break;
620 case OF_RECONFIG_UPDATE_PROPERTY:
621 __of_update_property_sysfs(ce->np, ce->prop, ce->old_prop);
622 break;
623 }
624
625 return 0;
626}
627
628static inline int __of_changeset_entry_revert(struct of_changeset_entry *ce)
629{
630 struct of_changeset_entry ce_inverted;
631
632 __of_changeset_entry_invert(ce, &ce_inverted);
633 return __of_changeset_entry_apply(&ce_inverted);
634}
635
636/**
637 * of_changeset_init - Initialize a changeset for use
638 *
639 * @ocs: changeset pointer
640 *
641 * Initialize a changeset structure
642 */
643void of_changeset_init(struct of_changeset *ocs)
644{
645 memset(ocs, 0, sizeof(*ocs));
646 INIT_LIST_HEAD(&ocs->entries);
647}
648
649/**
650 * of_changeset_destroy - Destroy a changeset
651 *
652 * @ocs: changeset pointer
653 *
654 * Destroys a changeset. Note that if a changeset is applied,
655 * its changes to the tree cannot be reverted.
656 */
657void of_changeset_destroy(struct of_changeset *ocs)
658{
659 struct of_changeset_entry *ce, *cen;
660
661 list_for_each_entry_safe_reverse(ce, cen, &ocs->entries, node)
662 __of_changeset_entry_destroy(ce);
663}
664
665/**
666 * of_changeset_apply - Applies a changeset
667 *
668 * @ocs: changeset pointer
669 *
670 * Applies a changeset to the live tree.
671 * Any side-effects of live tree state changes are applied here on
672 * sucess, like creation/destruction of devices and side-effects
673 * like creation of sysfs properties and directories.
674 * Returns 0 on success, a negative error value in case of an error.
675 * On error the partially applied effects are reverted.
676 */
677int of_changeset_apply(struct of_changeset *ocs)
678{
679 struct of_changeset_entry *ce;
680 int ret;
681
682 /* perform the rest of the work */
683 pr_debug("of_changeset: applying...\n");
684 list_for_each_entry(ce, &ocs->entries, node) {
685 ret = __of_changeset_entry_apply(ce);
686 if (ret) {
687 pr_err("%s: Error applying changeset (%d)\n", __func__, ret);
688 list_for_each_entry_continue_reverse(ce, &ocs->entries, node)
689 __of_changeset_entry_revert(ce);
690 return ret;
691 }
692 }
693 pr_debug("of_changeset: applied, emitting notifiers.\n");
694
695 /* drop the global lock while emitting notifiers */
696 mutex_unlock(&of_mutex);
697 list_for_each_entry(ce, &ocs->entries, node)
698 __of_changeset_entry_notify(ce, 0);
699 mutex_lock(&of_mutex);
700 pr_debug("of_changeset: notifiers sent.\n");
701
702 return 0;
703}
704
705/**
706 * of_changeset_revert - Reverts an applied changeset
707 *
708 * @ocs: changeset pointer
709 *
710 * Reverts a changeset returning the state of the tree to what it
711 * was before the application.
712 * Any side-effects like creation/destruction of devices and
713 * removal of sysfs properties and directories are applied.
714 * Returns 0 on success, a negative error value in case of an error.
715 */
716int of_changeset_revert(struct of_changeset *ocs)
717{
718 struct of_changeset_entry *ce;
719 int ret;
720
721 pr_debug("of_changeset: reverting...\n");
722 list_for_each_entry_reverse(ce, &ocs->entries, node) {
723 ret = __of_changeset_entry_revert(ce);
724 if (ret) {
725 pr_err("%s: Error reverting changeset (%d)\n", __func__, ret);
726 list_for_each_entry_continue(ce, &ocs->entries, node)
727 __of_changeset_entry_apply(ce);
728 return ret;
729 }
730 }
731 pr_debug("of_changeset: reverted, emitting notifiers.\n");
732
733 /* drop the global lock while emitting notifiers */
734 mutex_unlock(&of_mutex);
735 list_for_each_entry_reverse(ce, &ocs->entries, node)
736 __of_changeset_entry_notify(ce, 1);
737 mutex_lock(&of_mutex);
738 pr_debug("of_changeset: notifiers sent.\n");
739
740 return 0;
741}
742
743/**
744 * of_changeset_action - Perform a changeset action
745 *
746 * @ocs: changeset pointer
747 * @action: action to perform
748 * @np: Pointer to device node
749 * @prop: Pointer to property
750 *
751 * On action being one of:
752 * + OF_RECONFIG_ATTACH_NODE
753 * + OF_RECONFIG_DETACH_NODE,
754 * + OF_RECONFIG_ADD_PROPERTY
755 * + OF_RECONFIG_REMOVE_PROPERTY,
756 * + OF_RECONFIG_UPDATE_PROPERTY
757 * Returns 0 on success, a negative error value in case of an error.
758 */
759int of_changeset_action(struct of_changeset *ocs, unsigned long action,
760 struct device_node *np, struct property *prop)
761{
762 struct of_changeset_entry *ce;
763
764 ce = kzalloc(sizeof(*ce), GFP_KERNEL);
765 if (!ce) {
766 pr_err("%s: Failed to allocate\n", __func__);
767 return -ENOMEM;
768 }
769 /* get a reference to the node */
770 ce->action = action;
771 ce->np = of_node_get(np);
772 ce->prop = prop;
773
774 if (action == OF_RECONFIG_UPDATE_PROPERTY && prop)
775 ce->old_prop = of_find_property(np, prop->name, NULL);
776
777 /* add it to the list */
778 list_add_tail(&ce->node, &ocs->entries);
779 return 0;
780}