blob: 16524c8e95ec34cf03879eff0b5133ca9373bd0d [file] [log] [blame]
Grant Likely50788572014-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 Likely952f9f42014-07-23 17:05:06 -060044void __of_detach_node_sysfs(struct device_node *np)
Grant Likely50788572014-06-26 15:40:48 +010045{
46 struct property *pp;
47
48 BUG_ON(!of_node_is_initialized(np));
Grant Likely952f9f42014-07-23 17:05:06 -060049 if (!of_kset)
50 return;
Grant Likely50788572014-06-26 15:40:48 +010051
52 /* only remove properties if on sysfs */
53 if (of_node_is_attached(np)) {
54 for_each_property_of_node(np, pp)
55 sysfs_remove_bin_file(&np->kobj, &pp->attr);
56 kobject_del(&np->kobj);
57 }
58
59 /* finally remove the kobj_init ref */
60 of_node_put(np);
61}
62
63static BLOCKING_NOTIFIER_HEAD(of_reconfig_chain);
64
65int of_reconfig_notifier_register(struct notifier_block *nb)
66{
67 return blocking_notifier_chain_register(&of_reconfig_chain, nb);
68}
69EXPORT_SYMBOL_GPL(of_reconfig_notifier_register);
70
71int of_reconfig_notifier_unregister(struct notifier_block *nb)
72{
73 return blocking_notifier_chain_unregister(&of_reconfig_chain, nb);
74}
75EXPORT_SYMBOL_GPL(of_reconfig_notifier_unregister);
76
Grant Likely54c85512014-11-14 14:34:55 +000077#ifdef DEBUG
78const char *action_names[] = {
79 [OF_RECONFIG_ATTACH_NODE] = "ATTACH_NODE",
80 [OF_RECONFIG_DETACH_NODE] = "DETACH_NODE",
81 [OF_RECONFIG_ADD_PROPERTY] = "ADD_PROPERTY",
82 [OF_RECONFIG_REMOVE_PROPERTY] = "REMOVE_PROPERTY",
83 [OF_RECONFIG_UPDATE_PROPERTY] = "UPDATE_PROPERTY",
84};
85#endif
86
Grant Likelye60dc702014-11-24 17:58:01 +000087int of_reconfig_notify(unsigned long action, struct of_reconfig_data *p)
Grant Likely50788572014-06-26 15:40:48 +010088{
89 int rc;
Grant Likely54c85512014-11-14 14:34:55 +000090#ifdef DEBUG
Grant Likelye60dc702014-11-24 17:58:01 +000091 struct of_reconfig_data *pr = p;
Grant Likely50788572014-06-26 15:40:48 +010092
Grant Likely54c85512014-11-14 14:34:55 +000093 switch (action) {
94 case OF_RECONFIG_ATTACH_NODE:
95 case OF_RECONFIG_DETACH_NODE:
96 pr_debug("of/notify %-15s %s\n", action_names[action],
Grant Likelye60dc702014-11-24 17:58:01 +000097 pr->dn->full_name);
Grant Likely54c85512014-11-14 14:34:55 +000098 break;
99 case OF_RECONFIG_ADD_PROPERTY:
100 case OF_RECONFIG_REMOVE_PROPERTY:
101 case OF_RECONFIG_UPDATE_PROPERTY:
102 pr_debug("of/notify %-15s %s:%s\n", action_names[action],
103 pr->dn->full_name, pr->prop->name);
104 break;
105
106 }
107#endif
Grant Likely50788572014-06-26 15:40:48 +0100108 rc = blocking_notifier_call_chain(&of_reconfig_chain, action, p);
109 return notifier_to_errno(rc);
110}
111
Pantelis Antoniou8f2b7272014-10-28 22:33:53 +0200112/*
113 * of_reconfig_get_state_change() - Returns new state of device
114 * @action - action of the of notifier
115 * @arg - argument of the of notifier
116 *
117 * Returns the new state of a device based on the notifier used.
118 * Returns 0 on device going from enabled to disabled, 1 on device
119 * going from disabled to enabled and -1 on no change.
120 */
Grant Likelye60dc702014-11-24 17:58:01 +0000121int of_reconfig_get_state_change(unsigned long action, struct of_reconfig_data *pr)
Pantelis Antoniou8f2b7272014-10-28 22:33:53 +0200122{
Grant Likelye60dc702014-11-24 17:58:01 +0000123 struct property *prop, *old_prop = NULL;
Pantelis Antoniou8f2b7272014-10-28 22:33:53 +0200124 int is_status, status_state, old_status_state, prev_state, new_state;
125
126 /* figure out if a device should be created or destroyed */
Pantelis Antoniou8f2b7272014-10-28 22:33:53 +0200127 switch (action) {
128 case OF_RECONFIG_ATTACH_NODE:
129 case OF_RECONFIG_DETACH_NODE:
Grant Likelye60dc702014-11-24 17:58:01 +0000130 prop = of_find_property(pr->dn, "status", NULL);
Pantelis Antoniou8f2b7272014-10-28 22:33:53 +0200131 break;
132 case OF_RECONFIG_ADD_PROPERTY:
133 case OF_RECONFIG_REMOVE_PROPERTY:
Pantelis Antoniou8f2b7272014-10-28 22:33:53 +0200134 prop = pr->prop;
135 break;
136 case OF_RECONFIG_UPDATE_PROPERTY:
Pantelis Antoniou8f2b7272014-10-28 22:33:53 +0200137 prop = pr->prop;
138 old_prop = pr->old_prop;
139 break;
140 default:
141 return OF_RECONFIG_NO_CHANGE;
142 }
143
144 is_status = 0;
145 status_state = -1;
146 old_status_state = -1;
147 prev_state = -1;
148 new_state = -1;
149
150 if (prop && !strcmp(prop->name, "status")) {
151 is_status = 1;
152 status_state = !strcmp(prop->value, "okay") ||
153 !strcmp(prop->value, "ok");
154 if (old_prop)
155 old_status_state = !strcmp(old_prop->value, "okay") ||
156 !strcmp(old_prop->value, "ok");
157 }
158
159 switch (action) {
160 case OF_RECONFIG_ATTACH_NODE:
161 prev_state = 0;
162 /* -1 & 0 status either missing or okay */
163 new_state = status_state != 0;
164 break;
165 case OF_RECONFIG_DETACH_NODE:
166 /* -1 & 0 status either missing or okay */
167 prev_state = status_state != 0;
168 new_state = 0;
169 break;
170 case OF_RECONFIG_ADD_PROPERTY:
171 if (is_status) {
172 /* no status property -> enabled (legacy) */
173 prev_state = 1;
174 new_state = status_state;
175 }
176 break;
177 case OF_RECONFIG_REMOVE_PROPERTY:
178 if (is_status) {
179 prev_state = status_state;
180 /* no status property -> enabled (legacy) */
181 new_state = 1;
182 }
183 break;
184 case OF_RECONFIG_UPDATE_PROPERTY:
185 if (is_status) {
186 prev_state = old_status_state != 0;
187 new_state = status_state != 0;
188 }
189 break;
190 }
191
192 if (prev_state == new_state)
193 return OF_RECONFIG_NO_CHANGE;
194
195 return new_state ? OF_RECONFIG_CHANGE_ADD : OF_RECONFIG_CHANGE_REMOVE;
196}
197EXPORT_SYMBOL_GPL(of_reconfig_get_state_change);
198
Grant Likely50788572014-06-26 15:40:48 +0100199int of_property_notify(int action, struct device_node *np,
Grant Likely3e262052014-07-16 12:48:23 -0600200 struct property *prop, struct property *oldprop)
Grant Likely50788572014-06-26 15:40:48 +0100201{
Grant Likelye60dc702014-11-24 17:58:01 +0000202 struct of_reconfig_data pr;
Grant Likely50788572014-06-26 15:40:48 +0100203
204 /* only call notifiers if the node is attached */
205 if (!of_node_is_attached(np))
206 return 0;
207
208 pr.dn = np;
209 pr.prop = prop;
Grant Likely3e262052014-07-16 12:48:23 -0600210 pr.old_prop = oldprop;
Grant Likely50788572014-06-26 15:40:48 +0100211 return of_reconfig_notify(action, &pr);
212}
213
Pantelis Antoniou2189e1a2014-07-04 19:58:46 +0300214void __of_attach_node(struct device_node *np)
215{
Grant Likely3a09bee2014-07-15 23:25:43 -0600216 const __be32 *phandle;
217 int sz;
218
219 np->name = __of_get_property(np, "name", NULL) ? : "<NULL>";
220 np->type = __of_get_property(np, "device_type", NULL) ? : "<NULL>";
221
222 phandle = __of_get_property(np, "phandle", &sz);
223 if (!phandle)
224 phandle = __of_get_property(np, "linux,phandle", &sz);
225 if (IS_ENABLED(PPC_PSERIES) && !phandle)
226 phandle = __of_get_property(np, "ibm,phandle", &sz);
227 np->phandle = (phandle && (sz >= 4)) ? be32_to_cpup(phandle) : 0;
228
Grant Likely12f293f2014-07-16 08:48:46 -0600229 np->child = NULL;
Pantelis Antoniou2189e1a2014-07-04 19:58:46 +0300230 np->sibling = np->parent->child;
231 np->allnext = np->parent->allnext;
232 np->parent->allnext = np;
233 np->parent->child = np;
234 of_node_clear_flag(np, OF_DETACHED);
235}
236
Grant Likely50788572014-06-26 15:40:48 +0100237/**
238 * of_attach_node() - Plug a device node into the tree and global list.
239 */
240int of_attach_node(struct device_node *np)
241{
Grant Likelye60dc702014-11-24 17:58:01 +0000242 struct of_reconfig_data rd;
Grant Likely50788572014-06-26 15:40:48 +0100243 unsigned long flags;
Grant Likely50788572014-06-26 15:40:48 +0100244
Grant Likelye60dc702014-11-24 17:58:01 +0000245 memset(&rd, 0, sizeof(rd));
246 rd.dn = np;
247
Grant Likely952f9f42014-07-23 17:05:06 -0600248 mutex_lock(&of_mutex);
Grant Likely50788572014-06-26 15:40:48 +0100249 raw_spin_lock_irqsave(&devtree_lock, flags);
Pantelis Antoniou2189e1a2014-07-04 19:58:46 +0300250 __of_attach_node(np);
Grant Likely50788572014-06-26 15:40:48 +0100251 raw_spin_unlock_irqrestore(&devtree_lock, flags);
252
Grant Likely952f9f42014-07-23 17:05:06 -0600253 __of_attach_node_sysfs(np);
254 mutex_unlock(&of_mutex);
Grant Likely3e262052014-07-16 12:48:23 -0600255
Grant Likelye60dc702014-11-24 17:58:01 +0000256 of_reconfig_notify(OF_RECONFIG_ATTACH_NODE, &rd);
Grant Likely3e262052014-07-16 12:48:23 -0600257
Grant Likely50788572014-06-26 15:40:48 +0100258 return 0;
259}
260
Pantelis Antoniou2189e1a2014-07-04 19:58:46 +0300261void __of_detach_node(struct device_node *np)
Grant Likely50788572014-06-26 15:40:48 +0100262{
263 struct device_node *parent;
Grant Likely50788572014-06-26 15:40:48 +0100264
Pantelis Antoniou2189e1a2014-07-04 19:58:46 +0300265 if (WARN_ON(of_node_check_flag(np, OF_DETACHED)))
266 return;
Grant Likely50788572014-06-26 15:40:48 +0100267
268 parent = np->parent;
Pantelis Antoniou2189e1a2014-07-04 19:58:46 +0300269 if (WARN_ON(!parent))
270 return;
Grant Likely50788572014-06-26 15:40:48 +0100271
272 if (of_allnodes == np)
273 of_allnodes = np->allnext;
274 else {
275 struct device_node *prev;
276 for (prev = of_allnodes;
277 prev->allnext != np;
278 prev = prev->allnext)
279 ;
280 prev->allnext = np->allnext;
281 }
282
283 if (parent->child == np)
284 parent->child = np->sibling;
285 else {
286 struct device_node *prevsib;
287 for (prevsib = np->parent->child;
288 prevsib->sibling != np;
289 prevsib = prevsib->sibling)
290 ;
291 prevsib->sibling = np->sibling;
292 }
293
294 of_node_set_flag(np, OF_DETACHED);
Pantelis Antoniou2189e1a2014-07-04 19:58:46 +0300295}
296
297/**
298 * of_detach_node() - "Unplug" a node from the device tree.
299 *
300 * The caller must hold a reference to the node. The memory associated with
301 * the node is not freed until its refcount goes to zero.
302 */
303int of_detach_node(struct device_node *np)
304{
Grant Likelye60dc702014-11-24 17:58:01 +0000305 struct of_reconfig_data rd;
Pantelis Antoniou2189e1a2014-07-04 19:58:46 +0300306 unsigned long flags;
307 int rc = 0;
308
Grant Likelye60dc702014-11-24 17:58:01 +0000309 memset(&rd, 0, sizeof(rd));
310 rd.dn = np;
311
Grant Likely952f9f42014-07-23 17:05:06 -0600312 mutex_lock(&of_mutex);
Pantelis Antoniou2189e1a2014-07-04 19:58:46 +0300313 raw_spin_lock_irqsave(&devtree_lock, flags);
314 __of_detach_node(np);
Grant Likely50788572014-06-26 15:40:48 +0100315 raw_spin_unlock_irqrestore(&devtree_lock, flags);
316
Grant Likely952f9f42014-07-23 17:05:06 -0600317 __of_detach_node_sysfs(np);
318 mutex_unlock(&of_mutex);
Grant Likely3e262052014-07-16 12:48:23 -0600319
Grant Likelye60dc702014-11-24 17:58:01 +0000320 of_reconfig_notify(OF_RECONFIG_DETACH_NODE, &rd);
Grant Likely3e262052014-07-16 12:48:23 -0600321
Grant Likely50788572014-06-26 15:40:48 +0100322 return rc;
323}
324
325/**
326 * of_node_release() - release a dynamically allocated node
327 * @kref: kref element of the node to be released
328 *
329 * In of_node_put() this function is passed to kref_put() as the destructor.
330 */
331void of_node_release(struct kobject *kobj)
332{
333 struct device_node *node = kobj_to_device_node(kobj);
334 struct property *prop = node->properties;
335
336 /* We should never be releasing nodes that haven't been detached. */
337 if (!of_node_check_flag(node, OF_DETACHED)) {
338 pr_err("ERROR: Bad of_node_put() on %s\n", node->full_name);
339 dump_stack();
340 return;
341 }
342
343 if (!of_node_check_flag(node, OF_DYNAMIC))
344 return;
345
346 while (prop) {
347 struct property *next = prop->next;
348 kfree(prop->name);
349 kfree(prop->value);
350 kfree(prop);
351 prop = next;
352
353 if (!prop) {
354 prop = node->deadprops;
355 node->deadprops = NULL;
356 }
357 }
358 kfree(node->full_name);
359 kfree(node->data);
360 kfree(node);
361}
Pantelis Antoniouf713f5e2014-07-04 19:58:47 +0300362
363/**
364 * __of_prop_dup - Copy a property dynamically.
365 * @prop: Property to copy
366 * @allocflags: Allocation flags (typically pass GFP_KERNEL)
367 *
368 * Copy a property by dynamically allocating the memory of both the
369 * property stucture and the property name & contents. The property's
370 * flags have the OF_DYNAMIC bit set so that we can differentiate between
371 * dynamically allocated properties and not.
372 * Returns the newly allocated property or NULL on out of memory error.
373 */
374struct property *__of_prop_dup(const struct property *prop, gfp_t allocflags)
375{
376 struct property *new;
377
378 new = kzalloc(sizeof(*new), allocflags);
379 if (!new)
380 return NULL;
381
382 /*
383 * NOTE: There is no check for zero length value.
384 * In case of a boolean property This will allocate a value
385 * of zero bytes. We do this to work around the use
386 * of of_get_property() calls on boolean values.
387 */
388 new->name = kstrdup(prop->name, allocflags);
389 new->value = kmemdup(prop->value, prop->length, allocflags);
390 new->length = prop->length;
391 if (!new->name || !new->value)
392 goto err_free;
393
394 /* mark the property as dynamic */
395 of_property_set_flag(new, OF_DYNAMIC);
396
397 return new;
398
399 err_free:
400 kfree(new->name);
401 kfree(new->value);
402 kfree(new);
403 return NULL;
404}
405
406/**
Grant Likely1ee73732014-11-17 22:31:32 +0000407 * __of_node_dup() - Duplicate or create an empty device node dynamically.
408 * @fmt: Format string (plus vargs) for new full name of the device node
Pantelis Antoniouf713f5e2014-07-04 19:58:47 +0300409 *
Grant Likely1ee73732014-11-17 22:31:32 +0000410 * Create an device tree node, either by duplicating an empty node or by allocating
411 * an empty one suitable for further modification. The node data are
412 * dynamically allocated and all the node flags have the OF_DYNAMIC &
413 * OF_DETACHED bits set. Returns the newly allocated node or NULL on out of
414 * memory error.
Pantelis Antoniouf713f5e2014-07-04 19:58:47 +0300415 */
Grant Likely1ee73732014-11-17 22:31:32 +0000416struct device_node *__of_node_dup(const struct device_node *np, const char *fmt, ...)
Pantelis Antoniouf713f5e2014-07-04 19:58:47 +0300417{
Grant Likely644d38f2014-11-14 15:33:07 +0000418 va_list vargs;
Pantelis Antoniouf713f5e2014-07-04 19:58:47 +0300419 struct device_node *node;
420
Grant Likely644d38f2014-11-14 15:33:07 +0000421 node = kzalloc(sizeof(*node), GFP_KERNEL);
Pantelis Antoniouf713f5e2014-07-04 19:58:47 +0300422 if (!node)
423 return NULL;
Grant Likely644d38f2014-11-14 15:33:07 +0000424 va_start(vargs, fmt);
425 node->full_name = kvasprintf(GFP_KERNEL, fmt, vargs);
426 va_end(vargs);
Grant Likely1ee73732014-11-17 22:31:32 +0000427 if (!node->full_name) {
428 kfree(node);
429 return NULL;
430 }
Pantelis Antoniouf713f5e2014-07-04 19:58:47 +0300431
Grant Likely644d38f2014-11-14 15:33:07 +0000432 of_node_set_flag(node, OF_DYNAMIC);
433 of_node_set_flag(node, OF_DETACHED);
Pantelis Antoniouf713f5e2014-07-04 19:58:47 +0300434 of_node_init(node);
435
Grant Likely1ee73732014-11-17 22:31:32 +0000436 /* Iterate over and duplicate all properties */
437 if (np) {
438 struct property *pp, *new_pp;
439 for_each_property_of_node(np, pp) {
440 new_pp = __of_prop_dup(pp, GFP_KERNEL);
441 if (!new_pp)
442 goto err_prop;
443 if (__of_add_property(node, new_pp)) {
444 kfree(new_pp->name);
445 kfree(new_pp->value);
446 kfree(new_pp);
447 goto err_prop;
448 }
449 }
450 }
Pantelis Antoniouf713f5e2014-07-04 19:58:47 +0300451 return node;
452
Grant Likely1ee73732014-11-17 22:31:32 +0000453 err_prop:
454 of_node_put(node); /* Frees the node and properties */
Pantelis Antoniouf713f5e2014-07-04 19:58:47 +0300455 return NULL;
456}
Pantelis Antoniou67cf7732014-07-04 19:58:49 +0300457
458static void __of_changeset_entry_destroy(struct of_changeset_entry *ce)
459{
460 of_node_put(ce->np);
461 list_del(&ce->node);
462 kfree(ce);
463}
464
465#ifdef DEBUG
466static void __of_changeset_entry_dump(struct of_changeset_entry *ce)
467{
468 switch (ce->action) {
469 case OF_RECONFIG_ADD_PROPERTY:
Pantelis Antoniou67cf7732014-07-04 19:58:49 +0300470 case OF_RECONFIG_REMOVE_PROPERTY:
Pantelis Antoniou67cf7732014-07-04 19:58:49 +0300471 case OF_RECONFIG_UPDATE_PROPERTY:
Grant Likely54c85512014-11-14 14:34:55 +0000472 pr_debug("of/cset<%p> %-15s %s/%s\n", ce, action_names[ce->action],
473 ce->np->full_name, ce->prop->name);
Pantelis Antoniou67cf7732014-07-04 19:58:49 +0300474 break;
475 case OF_RECONFIG_ATTACH_NODE:
Pantelis Antoniou67cf7732014-07-04 19:58:49 +0300476 case OF_RECONFIG_DETACH_NODE:
Grant Likely54c85512014-11-14 14:34:55 +0000477 pr_debug("of/cset<%p> %-15s %s\n", ce, action_names[ce->action],
478 ce->np->full_name);
Pantelis Antoniou67cf7732014-07-04 19:58:49 +0300479 break;
480 }
481}
482#else
483static inline void __of_changeset_entry_dump(struct of_changeset_entry *ce)
484{
485 /* empty */
486}
487#endif
488
489static void __of_changeset_entry_invert(struct of_changeset_entry *ce,
490 struct of_changeset_entry *rce)
491{
492 memcpy(rce, ce, sizeof(*rce));
493
494 switch (ce->action) {
495 case OF_RECONFIG_ATTACH_NODE:
496 rce->action = OF_RECONFIG_DETACH_NODE;
497 break;
498 case OF_RECONFIG_DETACH_NODE:
499 rce->action = OF_RECONFIG_ATTACH_NODE;
500 break;
501 case OF_RECONFIG_ADD_PROPERTY:
502 rce->action = OF_RECONFIG_REMOVE_PROPERTY;
503 break;
504 case OF_RECONFIG_REMOVE_PROPERTY:
505 rce->action = OF_RECONFIG_ADD_PROPERTY;
506 break;
507 case OF_RECONFIG_UPDATE_PROPERTY:
508 rce->old_prop = ce->prop;
509 rce->prop = ce->old_prop;
510 break;
511 }
512}
513
514static void __of_changeset_entry_notify(struct of_changeset_entry *ce, bool revert)
515{
Grant Likelye60dc702014-11-24 17:58:01 +0000516 struct of_reconfig_data rd;
Pantelis Antoniou67cf7732014-07-04 19:58:49 +0300517 struct of_changeset_entry ce_inverted;
518 int ret;
519
520 if (revert) {
521 __of_changeset_entry_invert(ce, &ce_inverted);
522 ce = &ce_inverted;
523 }
524
525 switch (ce->action) {
526 case OF_RECONFIG_ATTACH_NODE:
527 case OF_RECONFIG_DETACH_NODE:
Grant Likelye60dc702014-11-24 17:58:01 +0000528 memset(&rd, 0, sizeof(rd));
529 rd.dn = ce->np;
530 ret = of_reconfig_notify(ce->action, &rd);
Pantelis Antoniou67cf7732014-07-04 19:58:49 +0300531 break;
532 case OF_RECONFIG_ADD_PROPERTY:
533 case OF_RECONFIG_REMOVE_PROPERTY:
534 case OF_RECONFIG_UPDATE_PROPERTY:
535 ret = of_property_notify(ce->action, ce->np, ce->prop, ce->old_prop);
536 break;
537 default:
538 pr_err("%s: invalid devicetree changeset action: %i\n", __func__,
539 (int)ce->action);
540 return;
541 }
542
543 if (ret)
544 pr_err("%s: notifier error @%s\n", __func__, ce->np->full_name);
545}
546
547static int __of_changeset_entry_apply(struct of_changeset_entry *ce)
548{
549 struct property *old_prop, **propp;
550 unsigned long flags;
551 int ret = 0;
552
553 __of_changeset_entry_dump(ce);
554
555 raw_spin_lock_irqsave(&devtree_lock, flags);
556 switch (ce->action) {
557 case OF_RECONFIG_ATTACH_NODE:
558 __of_attach_node(ce->np);
559 break;
560 case OF_RECONFIG_DETACH_NODE:
561 __of_detach_node(ce->np);
562 break;
563 case OF_RECONFIG_ADD_PROPERTY:
564 /* If the property is in deadprops then it must be removed */
565 for (propp = &ce->np->deadprops; *propp; propp = &(*propp)->next) {
566 if (*propp == ce->prop) {
567 *propp = ce->prop->next;
568 ce->prop->next = NULL;
569 break;
570 }
571 }
572
573 ret = __of_add_property(ce->np, ce->prop);
574 if (ret) {
575 pr_err("%s: add_property failed @%s/%s\n",
576 __func__, ce->np->full_name,
577 ce->prop->name);
578 break;
579 }
580 break;
581 case OF_RECONFIG_REMOVE_PROPERTY:
582 ret = __of_remove_property(ce->np, ce->prop);
583 if (ret) {
584 pr_err("%s: remove_property failed @%s/%s\n",
585 __func__, ce->np->full_name,
586 ce->prop->name);
587 break;
588 }
589 break;
590
591 case OF_RECONFIG_UPDATE_PROPERTY:
592 /* If the property is in deadprops then it must be removed */
593 for (propp = &ce->np->deadprops; *propp; propp = &(*propp)->next) {
594 if (*propp == ce->prop) {
595 *propp = ce->prop->next;
596 ce->prop->next = NULL;
597 break;
598 }
599 }
600
601 ret = __of_update_property(ce->np, ce->prop, &old_prop);
602 if (ret) {
603 pr_err("%s: update_property failed @%s/%s\n",
604 __func__, ce->np->full_name,
605 ce->prop->name);
606 break;
607 }
608 break;
609 default:
610 ret = -EINVAL;
611 }
612 raw_spin_unlock_irqrestore(&devtree_lock, flags);
613
614 if (ret)
615 return ret;
616
617 switch (ce->action) {
618 case OF_RECONFIG_ATTACH_NODE:
619 __of_attach_node_sysfs(ce->np);
620 break;
621 case OF_RECONFIG_DETACH_NODE:
622 __of_detach_node_sysfs(ce->np);
623 break;
624 case OF_RECONFIG_ADD_PROPERTY:
625 /* ignore duplicate names */
626 __of_add_property_sysfs(ce->np, ce->prop);
627 break;
628 case OF_RECONFIG_REMOVE_PROPERTY:
629 __of_remove_property_sysfs(ce->np, ce->prop);
630 break;
631 case OF_RECONFIG_UPDATE_PROPERTY:
632 __of_update_property_sysfs(ce->np, ce->prop, ce->old_prop);
633 break;
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 use
649 *
650 * @ocs: changeset pointer
651 *
652 * Initialize a changeset structure
653 */
654void of_changeset_init(struct of_changeset *ocs)
655{
656 memset(ocs, 0, sizeof(*ocs));
657 INIT_LIST_HEAD(&ocs->entries);
658}
659
660/**
661 * of_changeset_destroy - Destroy a changeset
662 *
663 * @ocs: changeset pointer
664 *
665 * Destroys a changeset. Note that if a changeset is applied,
666 * its changes to the tree cannot be reverted.
667 */
668void of_changeset_destroy(struct of_changeset *ocs)
669{
670 struct of_changeset_entry *ce, *cen;
671
672 list_for_each_entry_safe_reverse(ce, cen, &ocs->entries, node)
673 __of_changeset_entry_destroy(ce);
674}
675
676/**
677 * of_changeset_apply - Applies a changeset
678 *
679 * @ocs: changeset pointer
680 *
681 * Applies a changeset to the live tree.
682 * Any side-effects of live tree state changes are applied here on
683 * sucess, like creation/destruction of devices and side-effects
684 * like creation of sysfs properties and directories.
685 * Returns 0 on success, a negative error value in case of an error.
686 * On error the partially applied effects are reverted.
687 */
688int of_changeset_apply(struct of_changeset *ocs)
689{
690 struct of_changeset_entry *ce;
691 int ret;
692
693 /* perform the rest of the work */
694 pr_debug("of_changeset: applying...\n");
695 list_for_each_entry(ce, &ocs->entries, node) {
696 ret = __of_changeset_entry_apply(ce);
697 if (ret) {
698 pr_err("%s: Error applying changeset (%d)\n", __func__, ret);
699 list_for_each_entry_continue_reverse(ce, &ocs->entries, node)
700 __of_changeset_entry_revert(ce);
701 return ret;
702 }
703 }
704 pr_debug("of_changeset: applied, emitting notifiers.\n");
705
706 /* drop the global lock while emitting notifiers */
707 mutex_unlock(&of_mutex);
708 list_for_each_entry(ce, &ocs->entries, node)
709 __of_changeset_entry_notify(ce, 0);
710 mutex_lock(&of_mutex);
711 pr_debug("of_changeset: notifiers sent.\n");
712
713 return 0;
714}
715
716/**
717 * of_changeset_revert - Reverts an applied changeset
718 *
719 * @ocs: changeset pointer
720 *
721 * Reverts a changeset returning the state of the tree to what it
722 * was before the application.
723 * Any side-effects like creation/destruction of devices and
724 * removal of sysfs properties and directories are applied.
725 * Returns 0 on success, a negative error value in case of an error.
726 */
727int of_changeset_revert(struct of_changeset *ocs)
728{
729 struct of_changeset_entry *ce;
730 int ret;
731
732 pr_debug("of_changeset: reverting...\n");
733 list_for_each_entry_reverse(ce, &ocs->entries, node) {
734 ret = __of_changeset_entry_revert(ce);
735 if (ret) {
736 pr_err("%s: Error reverting changeset (%d)\n", __func__, ret);
737 list_for_each_entry_continue(ce, &ocs->entries, node)
738 __of_changeset_entry_apply(ce);
739 return ret;
740 }
741 }
742 pr_debug("of_changeset: reverted, emitting notifiers.\n");
743
744 /* drop the global lock while emitting notifiers */
745 mutex_unlock(&of_mutex);
746 list_for_each_entry_reverse(ce, &ocs->entries, node)
747 __of_changeset_entry_notify(ce, 1);
748 mutex_lock(&of_mutex);
749 pr_debug("of_changeset: notifiers sent.\n");
750
751 return 0;
752}
753
754/**
755 * of_changeset_action - Perform a changeset action
756 *
757 * @ocs: changeset pointer
758 * @action: action to perform
759 * @np: Pointer to device node
760 * @prop: Pointer to property
761 *
762 * On action being one of:
763 * + OF_RECONFIG_ATTACH_NODE
764 * + OF_RECONFIG_DETACH_NODE,
765 * + OF_RECONFIG_ADD_PROPERTY
766 * + OF_RECONFIG_REMOVE_PROPERTY,
767 * + OF_RECONFIG_UPDATE_PROPERTY
768 * Returns 0 on success, a negative error value in case of an error.
769 */
770int of_changeset_action(struct of_changeset *ocs, unsigned long action,
771 struct device_node *np, struct property *prop)
772{
773 struct of_changeset_entry *ce;
774
775 ce = kzalloc(sizeof(*ce), GFP_KERNEL);
776 if (!ce) {
777 pr_err("%s: Failed to allocate\n", __func__);
778 return -ENOMEM;
779 }
780 /* get a reference to the node */
781 ce->action = action;
782 ce->np = of_node_get(np);
783 ce->prop = prop;
784
785 if (action == OF_RECONFIG_UPDATE_PROPERTY && prop)
786 ce->old_prop = of_find_property(np, prop->name, NULL);
787
788 /* add it to the list */
789 list_add_tail(&ce->node, &ocs->entries);
790 return 0;
791}