]> Git Repo - linux.git/blob - drivers/of/dynamic.c
of/reconfig: Add empty stubs for the of_reconfig methods
[linux.git] / drivers / of / dynamic.c
1 /*
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  */
24 struct device_node *of_node_get(struct device_node *node)
25 {
26         if (node)
27                 kobject_get(&node->kobj);
28         return node;
29 }
30 EXPORT_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  */
37 void of_node_put(struct device_node *node)
38 {
39         if (node)
40                 kobject_put(&node->kobj);
41 }
42 EXPORT_SYMBOL(of_node_put);
43
44 void __of_detach_node_sysfs(struct device_node *np)
45 {
46         struct property *pp;
47
48         if (!IS_ENABLED(CONFIG_SYSFS))
49                 return;
50
51         BUG_ON(!of_node_is_initialized(np));
52         if (!of_kset)
53                 return;
54
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
66 static BLOCKING_NOTIFIER_HEAD(of_reconfig_chain);
67
68 int of_reconfig_notifier_register(struct notifier_block *nb)
69 {
70         return blocking_notifier_chain_register(&of_reconfig_chain, nb);
71 }
72 EXPORT_SYMBOL_GPL(of_reconfig_notifier_register);
73
74 int of_reconfig_notifier_unregister(struct notifier_block *nb)
75 {
76         return blocking_notifier_chain_unregister(&of_reconfig_chain, nb);
77 }
78 EXPORT_SYMBOL_GPL(of_reconfig_notifier_unregister);
79
80 int of_reconfig_notify(unsigned long action, void *p)
81 {
82         int rc;
83
84         rc = blocking_notifier_call_chain(&of_reconfig_chain, action, p);
85         return notifier_to_errno(rc);
86 }
87
88 /*
89  * of_reconfig_get_state_change()       - Returns new state of device
90  * @action      - action of the of notifier
91  * @arg         - argument of the of notifier
92  *
93  * Returns the new state of a device based on the notifier used.
94  * Returns 0 on device going from enabled to disabled, 1 on device
95  * going from disabled to enabled and -1 on no change.
96  */
97 int of_reconfig_get_state_change(unsigned long action, void *arg)
98 {
99         struct device_node *dn;
100         struct property *prop, *old_prop;
101         struct of_prop_reconfig *pr;
102         int is_status, status_state, old_status_state, prev_state, new_state;
103
104         /* figure out if a device should be created or destroyed */
105         dn = NULL;
106         prop = old_prop = NULL;
107         switch (action) {
108         case OF_RECONFIG_ATTACH_NODE:
109         case OF_RECONFIG_DETACH_NODE:
110                 dn = arg;
111                 prop = of_find_property(dn, "status", NULL);
112                 break;
113         case OF_RECONFIG_ADD_PROPERTY:
114         case OF_RECONFIG_REMOVE_PROPERTY:
115                 pr = arg;
116                 dn = pr->dn;
117                 prop = pr->prop;
118                 break;
119         case OF_RECONFIG_UPDATE_PROPERTY:
120                 pr = arg;
121                 dn = pr->dn;
122                 prop = pr->prop;
123                 old_prop = pr->old_prop;
124                 break;
125         default:
126                 return OF_RECONFIG_NO_CHANGE;
127         }
128
129         is_status = 0;
130         status_state = -1;
131         old_status_state = -1;
132         prev_state = -1;
133         new_state = -1;
134
135         if (prop && !strcmp(prop->name, "status")) {
136                 is_status = 1;
137                 status_state = !strcmp(prop->value, "okay") ||
138                                !strcmp(prop->value, "ok");
139                 if (old_prop)
140                         old_status_state = !strcmp(old_prop->value, "okay") ||
141                                            !strcmp(old_prop->value, "ok");
142         }
143
144         switch (action) {
145         case OF_RECONFIG_ATTACH_NODE:
146                 prev_state = 0;
147                 /* -1 & 0 status either missing or okay */
148                 new_state = status_state != 0;
149                 break;
150         case OF_RECONFIG_DETACH_NODE:
151                 /* -1 & 0 status either missing or okay */
152                 prev_state = status_state != 0;
153                 new_state = 0;
154                 break;
155         case OF_RECONFIG_ADD_PROPERTY:
156                 if (is_status) {
157                         /* no status property -> enabled (legacy) */
158                         prev_state = 1;
159                         new_state = status_state;
160                 }
161                 break;
162         case OF_RECONFIG_REMOVE_PROPERTY:
163                 if (is_status) {
164                         prev_state = status_state;
165                         /* no status property -> enabled (legacy) */
166                         new_state = 1;
167                 }
168                 break;
169         case OF_RECONFIG_UPDATE_PROPERTY:
170                 if (is_status) {
171                         prev_state = old_status_state != 0;
172                         new_state = status_state != 0;
173                 }
174                 break;
175         }
176
177         if (prev_state == new_state)
178                 return OF_RECONFIG_NO_CHANGE;
179
180         return new_state ? OF_RECONFIG_CHANGE_ADD : OF_RECONFIG_CHANGE_REMOVE;
181 }
182 EXPORT_SYMBOL_GPL(of_reconfig_get_state_change);
183
184 int of_property_notify(int action, struct device_node *np,
185                        struct property *prop, struct property *oldprop)
186 {
187         struct of_prop_reconfig pr;
188
189         /* only call notifiers if the node is attached */
190         if (!of_node_is_attached(np))
191                 return 0;
192
193         pr.dn = np;
194         pr.prop = prop;
195         pr.old_prop = oldprop;
196         return of_reconfig_notify(action, &pr);
197 }
198
199 void __of_attach_node(struct device_node *np)
200 {
201         const __be32 *phandle;
202         int sz;
203
204         np->name = __of_get_property(np, "name", NULL) ? : "<NULL>";
205         np->type = __of_get_property(np, "device_type", NULL) ? : "<NULL>";
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(PPC_PSERIES) && !phandle)
211                 phandle = __of_get_property(np, "ibm,phandle", &sz);
212         np->phandle = (phandle && (sz >= 4)) ? be32_to_cpup(phandle) : 0;
213
214         np->child = NULL;
215         np->sibling = np->parent->child;
216         np->parent->child = np;
217         of_node_clear_flag(np, OF_DETACHED);
218 }
219
220 /**
221  * of_attach_node() - Plug a device node into the tree and global list.
222  */
223 int of_attach_node(struct device_node *np)
224 {
225         unsigned long flags;
226
227         mutex_lock(&of_mutex);
228         raw_spin_lock_irqsave(&devtree_lock, flags);
229         __of_attach_node(np);
230         raw_spin_unlock_irqrestore(&devtree_lock, flags);
231
232         __of_attach_node_sysfs(np);
233         mutex_unlock(&of_mutex);
234
235         of_reconfig_notify(OF_RECONFIG_ATTACH_NODE, np);
236
237         return 0;
238 }
239
240 void __of_detach_node(struct device_node *np)
241 {
242         struct device_node *parent;
243
244         if (WARN_ON(of_node_check_flag(np, OF_DETACHED)))
245                 return;
246
247         parent = np->parent;
248         if (WARN_ON(!parent))
249                 return;
250
251         if (parent->child == np)
252                 parent->child = np->sibling;
253         else {
254                 struct device_node *prevsib;
255                 for (prevsib = np->parent->child;
256                      prevsib->sibling != np;
257                      prevsib = prevsib->sibling)
258                         ;
259                 prevsib->sibling = np->sibling;
260         }
261
262         of_node_set_flag(np, OF_DETACHED);
263 }
264
265 /**
266  * of_detach_node() - "Unplug" a node from the device tree.
267  *
268  * The caller must hold a reference to the node.  The memory associated with
269  * the node is not freed until its refcount goes to zero.
270  */
271 int of_detach_node(struct device_node *np)
272 {
273         unsigned long flags;
274         int rc = 0;
275
276         mutex_lock(&of_mutex);
277         raw_spin_lock_irqsave(&devtree_lock, flags);
278         __of_detach_node(np);
279         raw_spin_unlock_irqrestore(&devtree_lock, flags);
280
281         __of_detach_node_sysfs(np);
282         mutex_unlock(&of_mutex);
283
284         of_reconfig_notify(OF_RECONFIG_DETACH_NODE, np);
285
286         return rc;
287 }
288
289 /**
290  * of_node_release() - release a dynamically allocated node
291  * @kref: kref element of the node to be released
292  *
293  * In of_node_put() this function is passed to kref_put() as the destructor.
294  */
295 void of_node_release(struct kobject *kobj)
296 {
297         struct device_node *node = kobj_to_device_node(kobj);
298         struct property *prop = node->properties;
299
300         /* We should never be releasing nodes that haven't been detached. */
301         if (!of_node_check_flag(node, OF_DETACHED)) {
302                 pr_err("ERROR: Bad of_node_put() on %s\n", node->full_name);
303                 dump_stack();
304                 return;
305         }
306
307         if (!of_node_check_flag(node, OF_DYNAMIC))
308                 return;
309
310         while (prop) {
311                 struct property *next = prop->next;
312                 kfree(prop->name);
313                 kfree(prop->value);
314                 kfree(prop);
315                 prop = next;
316
317                 if (!prop) {
318                         prop = node->deadprops;
319                         node->deadprops = NULL;
320                 }
321         }
322         kfree(node->full_name);
323         kfree(node->data);
324         kfree(node);
325 }
326
327 /**
328  * __of_prop_dup - Copy a property dynamically.
329  * @prop:       Property to copy
330  * @allocflags: Allocation flags (typically pass GFP_KERNEL)
331  *
332  * Copy a property by dynamically allocating the memory of both the
333  * property structure and the property name & contents. The property's
334  * flags have the OF_DYNAMIC bit set so that we can differentiate between
335  * dynamically allocated properties and not.
336  * Returns the newly allocated property or NULL on out of memory error.
337  */
338 struct property *__of_prop_dup(const struct property *prop, gfp_t allocflags)
339 {
340         struct property *new;
341
342         new = kzalloc(sizeof(*new), allocflags);
343         if (!new)
344                 return NULL;
345
346         /*
347          * NOTE: There is no check for zero length value.
348          * In case of a boolean property, this will allocate a value
349          * of zero bytes. We do this to work around the use
350          * of of_get_property() calls on boolean values.
351          */
352         new->name = kstrdup(prop->name, allocflags);
353         new->value = kmemdup(prop->value, prop->length, allocflags);
354         new->length = prop->length;
355         if (!new->name || !new->value)
356                 goto err_free;
357
358         /* mark the property as dynamic */
359         of_property_set_flag(new, OF_DYNAMIC);
360
361         return new;
362
363  err_free:
364         kfree(new->name);
365         kfree(new->value);
366         kfree(new);
367         return NULL;
368 }
369
370 /**
371  * __of_node_dup() - Duplicate or create an empty device node dynamically.
372  * @fmt: Format string (plus vargs) for new full name of the device node
373  *
374  * Create an device tree node, either by duplicating an empty node or by allocating
375  * an empty one suitable for further modification.  The node data are
376  * dynamically allocated and all the node flags have the OF_DYNAMIC &
377  * OF_DETACHED bits set. Returns the newly allocated node or NULL on out of
378  * memory error.
379  */
380 struct device_node *__of_node_dup(const struct device_node *np, const char *fmt, ...)
381 {
382         va_list vargs;
383         struct device_node *node;
384
385         node = kzalloc(sizeof(*node), GFP_KERNEL);
386         if (!node)
387                 return NULL;
388         va_start(vargs, fmt);
389         node->full_name = kvasprintf(GFP_KERNEL, fmt, vargs);
390         va_end(vargs);
391         if (!node->full_name) {
392                 kfree(node);
393                 return NULL;
394         }
395
396         of_node_set_flag(node, OF_DYNAMIC);
397         of_node_set_flag(node, OF_DETACHED);
398         of_node_init(node);
399
400         /* Iterate over and duplicate all properties */
401         if (np) {
402                 struct property *pp, *new_pp;
403                 for_each_property_of_node(np, pp) {
404                         new_pp = __of_prop_dup(pp, GFP_KERNEL);
405                         if (!new_pp)
406                                 goto err_prop;
407                         if (__of_add_property(node, new_pp)) {
408                                 kfree(new_pp->name);
409                                 kfree(new_pp->value);
410                                 kfree(new_pp);
411                                 goto err_prop;
412                         }
413                 }
414         }
415         return node;
416
417  err_prop:
418         of_node_put(node); /* Frees the node and properties */
419         return NULL;
420 }
421
422 static void __of_changeset_entry_destroy(struct of_changeset_entry *ce)
423 {
424         of_node_put(ce->np);
425         list_del(&ce->node);
426         kfree(ce);
427 }
428
429 #ifdef DEBUG
430 static void __of_changeset_entry_dump(struct of_changeset_entry *ce)
431 {
432         switch (ce->action) {
433         case OF_RECONFIG_ADD_PROPERTY:
434                 pr_debug("%p: %s %s/%s\n",
435                         ce, "ADD_PROPERTY   ", ce->np->full_name,
436                         ce->prop->name);
437                 break;
438         case OF_RECONFIG_REMOVE_PROPERTY:
439                 pr_debug("%p: %s %s/%s\n",
440                         ce, "REMOVE_PROPERTY", ce->np->full_name,
441                         ce->prop->name);
442                 break;
443         case OF_RECONFIG_UPDATE_PROPERTY:
444                 pr_debug("%p: %s %s/%s\n",
445                         ce, "UPDATE_PROPERTY", ce->np->full_name,
446                         ce->prop->name);
447                 break;
448         case OF_RECONFIG_ATTACH_NODE:
449                 pr_debug("%p: %s %s\n",
450                         ce, "ATTACH_NODE    ", ce->np->full_name);
451                 break;
452         case OF_RECONFIG_DETACH_NODE:
453                 pr_debug("%p: %s %s\n",
454                         ce, "DETACH_NODE    ", ce->np->full_name);
455                 break;
456         }
457 }
458 #else
459 static inline void __of_changeset_entry_dump(struct of_changeset_entry *ce)
460 {
461         /* empty */
462 }
463 #endif
464
465 static void __of_changeset_entry_invert(struct of_changeset_entry *ce,
466                                           struct of_changeset_entry *rce)
467 {
468         memcpy(rce, ce, sizeof(*rce));
469
470         switch (ce->action) {
471         case OF_RECONFIG_ATTACH_NODE:
472                 rce->action = OF_RECONFIG_DETACH_NODE;
473                 break;
474         case OF_RECONFIG_DETACH_NODE:
475                 rce->action = OF_RECONFIG_ATTACH_NODE;
476                 break;
477         case OF_RECONFIG_ADD_PROPERTY:
478                 rce->action = OF_RECONFIG_REMOVE_PROPERTY;
479                 break;
480         case OF_RECONFIG_REMOVE_PROPERTY:
481                 rce->action = OF_RECONFIG_ADD_PROPERTY;
482                 break;
483         case OF_RECONFIG_UPDATE_PROPERTY:
484                 rce->old_prop = ce->prop;
485                 rce->prop = ce->old_prop;
486                 break;
487         }
488 }
489
490 static void __of_changeset_entry_notify(struct of_changeset_entry *ce, bool revert)
491 {
492         struct of_changeset_entry ce_inverted;
493         int ret;
494
495         if (revert) {
496                 __of_changeset_entry_invert(ce, &ce_inverted);
497                 ce = &ce_inverted;
498         }
499
500         switch (ce->action) {
501         case OF_RECONFIG_ATTACH_NODE:
502         case OF_RECONFIG_DETACH_NODE:
503                 ret = of_reconfig_notify(ce->action, ce->np);
504                 break;
505         case OF_RECONFIG_ADD_PROPERTY:
506         case OF_RECONFIG_REMOVE_PROPERTY:
507         case OF_RECONFIG_UPDATE_PROPERTY:
508                 ret = of_property_notify(ce->action, ce->np, ce->prop, ce->old_prop);
509                 break;
510         default:
511                 pr_err("%s: invalid devicetree changeset action: %i\n", __func__,
512                         (int)ce->action);
513                 return;
514         }
515
516         if (ret)
517                 pr_err("%s: notifier error @%s\n", __func__, ce->np->full_name);
518 }
519
520 static int __of_changeset_entry_apply(struct of_changeset_entry *ce)
521 {
522         struct property *old_prop, **propp;
523         unsigned long flags;
524         int ret = 0;
525
526         __of_changeset_entry_dump(ce);
527
528         raw_spin_lock_irqsave(&devtree_lock, flags);
529         switch (ce->action) {
530         case OF_RECONFIG_ATTACH_NODE:
531                 __of_attach_node(ce->np);
532                 break;
533         case OF_RECONFIG_DETACH_NODE:
534                 __of_detach_node(ce->np);
535                 break;
536         case OF_RECONFIG_ADD_PROPERTY:
537                 /* If the property is in deadprops then it must be removed */
538                 for (propp = &ce->np->deadprops; *propp; propp = &(*propp)->next) {
539                         if (*propp == ce->prop) {
540                                 *propp = ce->prop->next;
541                                 ce->prop->next = NULL;
542                                 break;
543                         }
544                 }
545
546                 ret = __of_add_property(ce->np, ce->prop);
547                 if (ret) {
548                         pr_err("%s: add_property failed @%s/%s\n",
549                                 __func__, ce->np->full_name,
550                                 ce->prop->name);
551                         break;
552                 }
553                 break;
554         case OF_RECONFIG_REMOVE_PROPERTY:
555                 ret = __of_remove_property(ce->np, ce->prop);
556                 if (ret) {
557                         pr_err("%s: remove_property failed @%s/%s\n",
558                                 __func__, ce->np->full_name,
559                                 ce->prop->name);
560                         break;
561                 }
562                 break;
563
564         case OF_RECONFIG_UPDATE_PROPERTY:
565                 /* If the property is in deadprops then it must be removed */
566                 for (propp = &ce->np->deadprops; *propp; propp = &(*propp)->next) {
567                         if (*propp == ce->prop) {
568                                 *propp = ce->prop->next;
569                                 ce->prop->next = NULL;
570                                 break;
571                         }
572                 }
573
574                 ret = __of_update_property(ce->np, ce->prop, &old_prop);
575                 if (ret) {
576                         pr_err("%s: update_property failed @%s/%s\n",
577                                 __func__, ce->np->full_name,
578                                 ce->prop->name);
579                         break;
580                 }
581                 break;
582         default:
583                 ret = -EINVAL;
584         }
585         raw_spin_unlock_irqrestore(&devtree_lock, flags);
586
587         if (ret)
588                 return ret;
589
590         switch (ce->action) {
591         case OF_RECONFIG_ATTACH_NODE:
592                 __of_attach_node_sysfs(ce->np);
593                 break;
594         case OF_RECONFIG_DETACH_NODE:
595                 __of_detach_node_sysfs(ce->np);
596                 break;
597         case OF_RECONFIG_ADD_PROPERTY:
598                 /* ignore duplicate names */
599                 __of_add_property_sysfs(ce->np, ce->prop);
600                 break;
601         case OF_RECONFIG_REMOVE_PROPERTY:
602                 __of_remove_property_sysfs(ce->np, ce->prop);
603                 break;
604         case OF_RECONFIG_UPDATE_PROPERTY:
605                 __of_update_property_sysfs(ce->np, ce->prop, ce->old_prop);
606                 break;
607         }
608
609         return 0;
610 }
611
612 static inline int __of_changeset_entry_revert(struct of_changeset_entry *ce)
613 {
614         struct of_changeset_entry ce_inverted;
615
616         __of_changeset_entry_invert(ce, &ce_inverted);
617         return __of_changeset_entry_apply(&ce_inverted);
618 }
619
620 /**
621  * of_changeset_init - Initialize a changeset for use
622  *
623  * @ocs:        changeset pointer
624  *
625  * Initialize a changeset structure
626  */
627 void of_changeset_init(struct of_changeset *ocs)
628 {
629         memset(ocs, 0, sizeof(*ocs));
630         INIT_LIST_HEAD(&ocs->entries);
631 }
632
633 /**
634  * of_changeset_destroy - Destroy a changeset
635  *
636  * @ocs:        changeset pointer
637  *
638  * Destroys a changeset. Note that if a changeset is applied,
639  * its changes to the tree cannot be reverted.
640  */
641 void of_changeset_destroy(struct of_changeset *ocs)
642 {
643         struct of_changeset_entry *ce, *cen;
644
645         list_for_each_entry_safe_reverse(ce, cen, &ocs->entries, node)
646                 __of_changeset_entry_destroy(ce);
647 }
648
649 /**
650  * of_changeset_apply - Applies a changeset
651  *
652  * @ocs:        changeset pointer
653  *
654  * Applies a changeset to the live tree.
655  * Any side-effects of live tree state changes are applied here on
656  * sucess, like creation/destruction of devices and side-effects
657  * like creation of sysfs properties and directories.
658  * Returns 0 on success, a negative error value in case of an error.
659  * On error the partially applied effects are reverted.
660  */
661 int of_changeset_apply(struct of_changeset *ocs)
662 {
663         struct of_changeset_entry *ce;
664         int ret;
665
666         /* perform the rest of the work */
667         pr_debug("of_changeset: applying...\n");
668         list_for_each_entry(ce, &ocs->entries, node) {
669                 ret = __of_changeset_entry_apply(ce);
670                 if (ret) {
671                         pr_err("%s: Error applying changeset (%d)\n", __func__, ret);
672                         list_for_each_entry_continue_reverse(ce, &ocs->entries, node)
673                                 __of_changeset_entry_revert(ce);
674                         return ret;
675                 }
676         }
677         pr_debug("of_changeset: applied, emitting notifiers.\n");
678
679         /* drop the global lock while emitting notifiers */
680         mutex_unlock(&of_mutex);
681         list_for_each_entry(ce, &ocs->entries, node)
682                 __of_changeset_entry_notify(ce, 0);
683         mutex_lock(&of_mutex);
684         pr_debug("of_changeset: notifiers sent.\n");
685
686         return 0;
687 }
688
689 /**
690  * of_changeset_revert - Reverts an applied changeset
691  *
692  * @ocs:        changeset pointer
693  *
694  * Reverts a changeset returning the state of the tree to what it
695  * was before the application.
696  * Any side-effects like creation/destruction of devices and
697  * removal of sysfs properties and directories are applied.
698  * Returns 0 on success, a negative error value in case of an error.
699  */
700 int of_changeset_revert(struct of_changeset *ocs)
701 {
702         struct of_changeset_entry *ce;
703         int ret;
704
705         pr_debug("of_changeset: reverting...\n");
706         list_for_each_entry_reverse(ce, &ocs->entries, node) {
707                 ret = __of_changeset_entry_revert(ce);
708                 if (ret) {
709                         pr_err("%s: Error reverting changeset (%d)\n", __func__, ret);
710                         list_for_each_entry_continue(ce, &ocs->entries, node)
711                                 __of_changeset_entry_apply(ce);
712                         return ret;
713                 }
714         }
715         pr_debug("of_changeset: reverted, emitting notifiers.\n");
716
717         /* drop the global lock while emitting notifiers */
718         mutex_unlock(&of_mutex);
719         list_for_each_entry_reverse(ce, &ocs->entries, node)
720                 __of_changeset_entry_notify(ce, 1);
721         mutex_lock(&of_mutex);
722         pr_debug("of_changeset: notifiers sent.\n");
723
724         return 0;
725 }
726
727 /**
728  * of_changeset_action - Perform a changeset action
729  *
730  * @ocs:        changeset pointer
731  * @action:     action to perform
732  * @np:         Pointer to device node
733  * @prop:       Pointer to property
734  *
735  * On action being one of:
736  * + OF_RECONFIG_ATTACH_NODE
737  * + OF_RECONFIG_DETACH_NODE,
738  * + OF_RECONFIG_ADD_PROPERTY
739  * + OF_RECONFIG_REMOVE_PROPERTY,
740  * + OF_RECONFIG_UPDATE_PROPERTY
741  * Returns 0 on success, a negative error value in case of an error.
742  */
743 int of_changeset_action(struct of_changeset *ocs, unsigned long action,
744                 struct device_node *np, struct property *prop)
745 {
746         struct of_changeset_entry *ce;
747
748         ce = kzalloc(sizeof(*ce), GFP_KERNEL);
749         if (!ce) {
750                 pr_err("%s: Failed to allocate\n", __func__);
751                 return -ENOMEM;
752         }
753         /* get a reference to the node */
754         ce->action = action;
755         ce->np = of_node_get(np);
756         ce->prop = prop;
757
758         if (action == OF_RECONFIG_UPDATE_PROPERTY && prop)
759                 ce->old_prop = of_find_property(np, prop->name, NULL);
760
761         /* add it to the list */
762         list_add_tail(&ce->node, &ocs->entries);
763         return 0;
764 }
This page took 0.077129 seconds and 4 git commands to generate.