aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/of/dynamic.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2014-12-11 16:06:58 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2014-12-11 16:06:58 -0500
commit7ef58b32f571bffb7763c6252ad7527562081f34 (patch)
tree6d1493304ec7a47e4d9e3e84dc9f6e53547dff91 /drivers/of/dynamic.c
parent413fd0e3fbf52873f2310eb75bfa6c7b72847277 (diff)
parentc46ca3c8310b61d253a39ff1375ea97912794cd1 (diff)
Merge tag 'devicetree-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/glikely/linux
Pull devicetree changes from Grant Likely: "Lots of activity in the devicetree code for v3.18. Most of it is related to getting all of the overlay support code in place, but there are other important things in there. Highlights: - OF_RECONFIG notifiers for SPI, I2C and Platform devices. Those subsystems can now respond to live changes to the device tree. - CONFIG_OF_OVERLAY method for applying live changes to the device tree - Removal of the of_allnodes list. This used to be used to iterate over all the nodes in the device tree, but it is unnecessary because the same thing can be done by iterating over the list of child pointers. Getting rid of of_allnodes saves some memory and avoids the possibility of of_allnodes being sorted differently from the child lists. - Support for retrieving original DTB blob via sysfs. Needed by kexec. - More unittests - Documentation and minor bug fixes" * tag 'devicetree-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/glikely/linux: (42 commits) of: Delete unnecessary check before calling "of_node_put()" of: Drop ->next pointer from struct device_node spi: Check for spi_of_notifier when CONFIG_OF_DYNAMIC=y of: support passing console options with stdout-path of: add optional options parameter to of_find_node_by_path() of: Add bindings for chosen node, stdout-path of: Remove unneeded and incorrect MODULE_DEVICE_TABLE ARM: dt: fix up PL011 device tree bindings of: base, fix of_property_read_string_helper kernel-doc of: remove select of non-existant OF_DEVICE config symbol spi/of: Add OF notifier handler spi/of: Create new device registration method and accessors i2c/of: Add OF_RECONFIG notifier handler i2c/of: Factor out Devicetree registration code of/overlay: Add overlay unittests of/overlay: Introduce DT overlay support of/reconfig: Add OF_DYNAMIC notifier for platform_bus_type of/reconfig: Always use the same structure for notifiers of/reconfig: Add debug output for OF_RECONFIG notifiers of/reconfig: Add empty stubs for the of_reconfig methods ...
Diffstat (limited to 'drivers/of/dynamic.c')
-rw-r--r--drivers/of/dynamic.c218
1 files changed, 168 insertions, 50 deletions
diff --git a/drivers/of/dynamic.c b/drivers/of/dynamic.c
index d4994177dec2..3351ef408125 100644
--- a/drivers/of/dynamic.c
+++ b/drivers/of/dynamic.c
@@ -77,18 +77,132 @@ int of_reconfig_notifier_unregister(struct notifier_block *nb)
77} 77}
78EXPORT_SYMBOL_GPL(of_reconfig_notifier_unregister); 78EXPORT_SYMBOL_GPL(of_reconfig_notifier_unregister);
79 79
80int of_reconfig_notify(unsigned long action, void *p) 80#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
90int of_reconfig_notify(unsigned long action, struct of_reconfig_data *p)
81{ 91{
82 int rc; 92 int rc;
93#ifdef DEBUG
94 struct of_reconfig_data *pr = p;
95
96 switch (action) {
97 case OF_RECONFIG_ATTACH_NODE:
98 case OF_RECONFIG_DETACH_NODE:
99 pr_debug("of/notify %-15s %s\n", action_names[action],
100 pr->dn->full_name);
101 break;
102 case OF_RECONFIG_ADD_PROPERTY:
103 case OF_RECONFIG_REMOVE_PROPERTY:
104 case OF_RECONFIG_UPDATE_PROPERTY:
105 pr_debug("of/notify %-15s %s:%s\n", action_names[action],
106 pr->dn->full_name, pr->prop->name);
107 break;
83 108
109 }
110#endif
84 rc = blocking_notifier_call_chain(&of_reconfig_chain, action, p); 111 rc = blocking_notifier_call_chain(&of_reconfig_chain, action, p);
85 return notifier_to_errno(rc); 112 return notifier_to_errno(rc);
86} 113}
87 114
115/*
116 * of_reconfig_get_state_change() - Returns new state of device
117 * @action - action of the of notifier
118 * @arg - argument of the of notifier
119 *
120 * Returns the new state of a device based on the notifier used.
121 * Returns 0 on device going from enabled to disabled, 1 on device
122 * going from disabled to enabled and -1 on no change.
123 */
124int of_reconfig_get_state_change(unsigned long action, struct of_reconfig_data *pr)
125{
126 struct property *prop, *old_prop = NULL;
127 int is_status, status_state, old_status_state, prev_state, new_state;
128
129 /* figure out if a device should be created or destroyed */
130 switch (action) {
131 case OF_RECONFIG_ATTACH_NODE:
132 case OF_RECONFIG_DETACH_NODE:
133 prop = of_find_property(pr->dn, "status", NULL);
134 break;
135 case OF_RECONFIG_ADD_PROPERTY:
136 case OF_RECONFIG_REMOVE_PROPERTY:
137 prop = pr->prop;
138 break;
139 case OF_RECONFIG_UPDATE_PROPERTY:
140 prop = pr->prop;
141 old_prop = pr->old_prop;
142 break;
143 default:
144 return OF_RECONFIG_NO_CHANGE;
145 }
146
147 is_status = 0;
148 status_state = -1;
149 old_status_state = -1;
150 prev_state = -1;
151 new_state = -1;
152
153 if (prop && !strcmp(prop->name, "status")) {
154 is_status = 1;
155 status_state = !strcmp(prop->value, "okay") ||
156 !strcmp(prop->value, "ok");
157 if (old_prop)
158 old_status_state = !strcmp(old_prop->value, "okay") ||
159 !strcmp(old_prop->value, "ok");
160 }
161
162 switch (action) {
163 case OF_RECONFIG_ATTACH_NODE:
164 prev_state = 0;
165 /* -1 & 0 status either missing or okay */
166 new_state = status_state != 0;
167 break;
168 case OF_RECONFIG_DETACH_NODE:
169 /* -1 & 0 status either missing or okay */
170 prev_state = status_state != 0;
171 new_state = 0;
172 break;
173 case OF_RECONFIG_ADD_PROPERTY:
174 if (is_status) {
175 /* no status property -> enabled (legacy) */
176 prev_state = 1;
177 new_state = status_state;
178 }
179 break;
180 case OF_RECONFIG_REMOVE_PROPERTY:
181 if (is_status) {
182 prev_state = status_state;
183 /* no status property -> enabled (legacy) */
184 new_state = 1;
185 }
186 break;
187 case OF_RECONFIG_UPDATE_PROPERTY:
188 if (is_status) {
189 prev_state = old_status_state != 0;
190 new_state = status_state != 0;
191 }
192 break;
193 }
194
195 if (prev_state == new_state)
196 return OF_RECONFIG_NO_CHANGE;
197
198 return new_state ? OF_RECONFIG_CHANGE_ADD : OF_RECONFIG_CHANGE_REMOVE;
199}
200EXPORT_SYMBOL_GPL(of_reconfig_get_state_change);
201
88int of_property_notify(int action, struct device_node *np, 202int of_property_notify(int action, struct device_node *np,
89 struct property *prop, struct property *oldprop) 203 struct property *prop, struct property *oldprop)
90{ 204{
91 struct of_prop_reconfig pr; 205 struct of_reconfig_data pr;
92 206
93 /* only call notifiers if the node is attached */ 207 /* only call notifiers if the node is attached */
94 if (!of_node_is_attached(np)) 208 if (!of_node_is_attached(np))
@@ -117,8 +231,6 @@ void __of_attach_node(struct device_node *np)
117 231
118 np->child = NULL; 232 np->child = NULL;
119 np->sibling = np->parent->child; 233 np->sibling = np->parent->child;
120 np->allnext = np->parent->allnext;
121 np->parent->allnext = np;
122 np->parent->child = np; 234 np->parent->child = np;
123 of_node_clear_flag(np, OF_DETACHED); 235 of_node_clear_flag(np, OF_DETACHED);
124} 236}
@@ -128,8 +240,12 @@ void __of_attach_node(struct device_node *np)
128 */ 240 */
129int of_attach_node(struct device_node *np) 241int of_attach_node(struct device_node *np)
130{ 242{
243 struct of_reconfig_data rd;
131 unsigned long flags; 244 unsigned long flags;
132 245
246 memset(&rd, 0, sizeof(rd));
247 rd.dn = np;
248
133 mutex_lock(&of_mutex); 249 mutex_lock(&of_mutex);
134 raw_spin_lock_irqsave(&devtree_lock, flags); 250 raw_spin_lock_irqsave(&devtree_lock, flags);
135 __of_attach_node(np); 251 __of_attach_node(np);
@@ -138,7 +254,7 @@ int of_attach_node(struct device_node *np)
138 __of_attach_node_sysfs(np); 254 __of_attach_node_sysfs(np);
139 mutex_unlock(&of_mutex); 255 mutex_unlock(&of_mutex);
140 256
141 of_reconfig_notify(OF_RECONFIG_ATTACH_NODE, np); 257 of_reconfig_notify(OF_RECONFIG_ATTACH_NODE, &rd);
142 258
143 return 0; 259 return 0;
144} 260}
@@ -154,17 +270,6 @@ void __of_detach_node(struct device_node *np)
154 if (WARN_ON(!parent)) 270 if (WARN_ON(!parent))
155 return; 271 return;
156 272
157 if (of_allnodes == np)
158 of_allnodes = np->allnext;
159 else {
160 struct device_node *prev;
161 for (prev = of_allnodes;
162 prev->allnext != np;
163 prev = prev->allnext)
164 ;
165 prev->allnext = np->allnext;
166 }
167
168 if (parent->child == np) 273 if (parent->child == np)
169 parent->child = np->sibling; 274 parent->child = np->sibling;
170 else { 275 else {
@@ -187,9 +292,13 @@ void __of_detach_node(struct device_node *np)
187 */ 292 */
188int of_detach_node(struct device_node *np) 293int of_detach_node(struct device_node *np)
189{ 294{
295 struct of_reconfig_data rd;
190 unsigned long flags; 296 unsigned long flags;
191 int rc = 0; 297 int rc = 0;
192 298
299 memset(&rd, 0, sizeof(rd));
300 rd.dn = np;
301
193 mutex_lock(&of_mutex); 302 mutex_lock(&of_mutex);
194 raw_spin_lock_irqsave(&devtree_lock, flags); 303 raw_spin_lock_irqsave(&devtree_lock, flags);
195 __of_detach_node(np); 304 __of_detach_node(np);
@@ -198,7 +307,7 @@ int of_detach_node(struct device_node *np)
198 __of_detach_node_sysfs(np); 307 __of_detach_node_sysfs(np);
199 mutex_unlock(&of_mutex); 308 mutex_unlock(&of_mutex);
200 309
201 of_reconfig_notify(OF_RECONFIG_DETACH_NODE, np); 310 of_reconfig_notify(OF_RECONFIG_DETACH_NODE, &rd);
202 311
203 return rc; 312 return rc;
204} 313}
@@ -285,36 +394,54 @@ struct property *__of_prop_dup(const struct property *prop, gfp_t allocflags)
285} 394}
286 395
287/** 396/**
288 * __of_node_alloc() - Create an empty device node dynamically. 397 * __of_node_dup() - Duplicate or create an empty device node dynamically.
289 * @full_name: Full name of the new device node 398 * @fmt: Format string (plus vargs) for new full name of the device node
290 * @allocflags: Allocation flags (typically pass GFP_KERNEL)
291 * 399 *
292 * Create an empty device tree node, suitable for further modification. 400 * Create an device tree node, either by duplicating an empty node or by allocating
293 * The node data are dynamically allocated and all the node flags 401 * an empty one suitable for further modification. The node data are
294 * have the OF_DYNAMIC & OF_DETACHED bits set. 402 * dynamically allocated and all the node flags have the OF_DYNAMIC &
295 * Returns the newly allocated node or NULL on out of memory error. 403 * OF_DETACHED bits set. Returns the newly allocated node or NULL on out of
404 * memory error.
296 */ 405 */
297struct device_node *__of_node_alloc(const char *full_name, gfp_t allocflags) 406struct device_node *__of_node_dup(const struct device_node *np, const char *fmt, ...)
298{ 407{
408 va_list vargs;
299 struct device_node *node; 409 struct device_node *node;
300 410
301 node = kzalloc(sizeof(*node), allocflags); 411 node = kzalloc(sizeof(*node), GFP_KERNEL);
302 if (!node) 412 if (!node)
303 return NULL; 413 return NULL;
414 va_start(vargs, fmt);
415 node->full_name = kvasprintf(GFP_KERNEL, fmt, vargs);
416 va_end(vargs);
417 if (!node->full_name) {
418 kfree(node);
419 return NULL;
420 }
304 421
305 node->full_name = kstrdup(full_name, allocflags);
306 of_node_set_flag(node, OF_DYNAMIC); 422 of_node_set_flag(node, OF_DYNAMIC);
307 of_node_set_flag(node, OF_DETACHED); 423 of_node_set_flag(node, OF_DETACHED);
308 if (!node->full_name)
309 goto err_free;
310
311 of_node_init(node); 424 of_node_init(node);
312 425
426 /* Iterate over and duplicate all properties */
427 if (np) {
428 struct property *pp, *new_pp;
429 for_each_property_of_node(np, pp) {
430 new_pp = __of_prop_dup(pp, GFP_KERNEL);
431 if (!new_pp)
432 goto err_prop;
433 if (__of_add_property(node, new_pp)) {
434 kfree(new_pp->name);
435 kfree(new_pp->value);
436 kfree(new_pp);
437 goto err_prop;
438 }
439 }
440 }
313 return node; 441 return node;
314 442
315 err_free: 443 err_prop:
316 kfree(node->full_name); 444 of_node_put(node); /* Frees the node and properties */
317 kfree(node);
318 return NULL; 445 return NULL;
319} 446}
320 447
@@ -330,27 +457,15 @@ static void __of_changeset_entry_dump(struct of_changeset_entry *ce)
330{ 457{
331 switch (ce->action) { 458 switch (ce->action) {
332 case OF_RECONFIG_ADD_PROPERTY: 459 case OF_RECONFIG_ADD_PROPERTY:
333 pr_debug("%p: %s %s/%s\n",
334 ce, "ADD_PROPERTY ", ce->np->full_name,
335 ce->prop->name);
336 break;
337 case OF_RECONFIG_REMOVE_PROPERTY: 460 case OF_RECONFIG_REMOVE_PROPERTY:
338 pr_debug("%p: %s %s/%s\n",
339 ce, "REMOVE_PROPERTY", ce->np->full_name,
340 ce->prop->name);
341 break;
342 case OF_RECONFIG_UPDATE_PROPERTY: 461 case OF_RECONFIG_UPDATE_PROPERTY:
343 pr_debug("%p: %s %s/%s\n", 462 pr_debug("of/cset<%p> %-15s %s/%s\n", ce, action_names[ce->action],
344 ce, "UPDATE_PROPERTY", ce->np->full_name, 463 ce->np->full_name, ce->prop->name);
345 ce->prop->name);
346 break; 464 break;
347 case OF_RECONFIG_ATTACH_NODE: 465 case OF_RECONFIG_ATTACH_NODE:
348 pr_debug("%p: %s %s\n",
349 ce, "ATTACH_NODE ", ce->np->full_name);
350 break;
351 case OF_RECONFIG_DETACH_NODE: 466 case OF_RECONFIG_DETACH_NODE:
352 pr_debug("%p: %s %s\n", 467 pr_debug("of/cset<%p> %-15s %s\n", ce, action_names[ce->action],
353 ce, "DETACH_NODE ", ce->np->full_name); 468 ce->np->full_name);
354 break; 469 break;
355 } 470 }
356} 471}
@@ -388,6 +503,7 @@ static void __of_changeset_entry_invert(struct of_changeset_entry *ce,
388 503
389static void __of_changeset_entry_notify(struct of_changeset_entry *ce, bool revert) 504static void __of_changeset_entry_notify(struct of_changeset_entry *ce, bool revert)
390{ 505{
506 struct of_reconfig_data rd;
391 struct of_changeset_entry ce_inverted; 507 struct of_changeset_entry ce_inverted;
392 int ret; 508 int ret;
393 509
@@ -399,7 +515,9 @@ static void __of_changeset_entry_notify(struct of_changeset_entry *ce, bool reve
399 switch (ce->action) { 515 switch (ce->action) {
400 case OF_RECONFIG_ATTACH_NODE: 516 case OF_RECONFIG_ATTACH_NODE:
401 case OF_RECONFIG_DETACH_NODE: 517 case OF_RECONFIG_DETACH_NODE:
402 ret = of_reconfig_notify(ce->action, ce->np); 518 memset(&rd, 0, sizeof(rd));
519 rd.dn = ce->np;
520 ret = of_reconfig_notify(ce->action, &rd);
403 break; 521 break;
404 case OF_RECONFIG_ADD_PROPERTY: 522 case OF_RECONFIG_ADD_PROPERTY:
405 case OF_RECONFIG_REMOVE_PROPERTY: 523 case OF_RECONFIG_REMOVE_PROPERTY: