aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDong Aisheng <dong.aisheng@linaro.org>2012-07-11 01:16:37 -0400
committerBenjamin Herrenschmidt <benh@kernel.crashing.org>2012-07-11 01:26:51 -0400
commit475d0094293b51353e342d1198377967dbc48169 (patch)
treeb10a01706dd433b93353600a00491ce62e385ec9
parentb416c9a10baae6a177b4f9ee858b8d309542fbef (diff)
of: Improve prom_update_property() function
prom_update_property() currently fails if the property doesn't actually exist yet which isn't what we want. Change to add-or-update instead of update-only, then we can remove a lot duplicated lines. Suggested-by: Grant Likely <grant.likely@secretlab.ca> Signed-off-by: Dong Aisheng <dong.aisheng@linaro.org> Acked-by: Rob Herring <rob.herring@calxeda.com> Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
-rw-r--r--arch/powerpc/platforms/85xx/p1022_ds.c8
-rw-r--r--arch/powerpc/platforms/pseries/mobility.c8
-rw-r--r--arch/powerpc/platforms/pseries/reconfig.c16
-rw-r--r--drivers/of/base.c15
-rw-r--r--fs/proc/proc_devtree.c5
-rw-r--r--include/linux/of.h3
6 files changed, 25 insertions, 30 deletions
diff --git a/arch/powerpc/platforms/85xx/p1022_ds.c b/arch/powerpc/platforms/85xx/p1022_ds.c
index 74e310b4b460..31d18b964f94 100644
--- a/arch/powerpc/platforms/85xx/p1022_ds.c
+++ b/arch/powerpc/platforms/85xx/p1022_ds.c
@@ -348,13 +348,7 @@ void __init p1022_ds_pic_init(void)
348 */ 348 */
349static void __init disable_one_node(struct device_node *np, struct property *new) 349static void __init disable_one_node(struct device_node *np, struct property *new)
350{ 350{
351 struct property *old; 351 prom_update_property(np, new);
352
353 old = of_find_property(np, new->name, NULL);
354 if (old)
355 prom_update_property(np, new, old);
356 else
357 prom_add_property(np, new);
358} 352}
359 353
360/* TRUE if there is a "video=fslfb" command-line parameter. */ 354/* TRUE if there is a "video=fslfb" command-line parameter. */
diff --git a/arch/powerpc/platforms/pseries/mobility.c b/arch/powerpc/platforms/pseries/mobility.c
index 029a562af373..dd30b12edfe4 100644
--- a/arch/powerpc/platforms/pseries/mobility.c
+++ b/arch/powerpc/platforms/pseries/mobility.c
@@ -67,7 +67,6 @@ static int update_dt_property(struct device_node *dn, struct property **prop,
67 const char *name, u32 vd, char *value) 67 const char *name, u32 vd, char *value)
68{ 68{
69 struct property *new_prop = *prop; 69 struct property *new_prop = *prop;
70 struct property *old_prop;
71 int more = 0; 70 int more = 0;
72 71
73 /* A negative 'vd' value indicates that only part of the new property 72 /* A negative 'vd' value indicates that only part of the new property
@@ -117,12 +116,7 @@ static int update_dt_property(struct device_node *dn, struct property **prop,
117 } 116 }
118 117
119 if (!more) { 118 if (!more) {
120 old_prop = of_find_property(dn, new_prop->name, NULL); 119 prom_update_property(dn, new_prop);
121 if (old_prop)
122 prom_update_property(dn, new_prop, old_prop);
123 else
124 prom_add_property(dn, new_prop);
125
126 new_prop = NULL; 120 new_prop = NULL;
127 } 121 }
128 122
diff --git a/arch/powerpc/platforms/pseries/reconfig.c b/arch/powerpc/platforms/pseries/reconfig.c
index 7b3bf76ef834..39f71fba9b38 100644
--- a/arch/powerpc/platforms/pseries/reconfig.c
+++ b/arch/powerpc/platforms/pseries/reconfig.c
@@ -432,7 +432,7 @@ static int do_update_property(char *buf, size_t bufsize)
432 unsigned char *value; 432 unsigned char *value;
433 char *name, *end, *next_prop; 433 char *name, *end, *next_prop;
434 int rc, length; 434 int rc, length;
435 struct property *newprop, *oldprop; 435 struct property *newprop;
436 buf = parse_node(buf, bufsize, &np); 436 buf = parse_node(buf, bufsize, &np);
437 end = buf + bufsize; 437 end = buf + bufsize;
438 438
@@ -443,6 +443,9 @@ static int do_update_property(char *buf, size_t bufsize)
443 if (!next_prop) 443 if (!next_prop)
444 return -EINVAL; 444 return -EINVAL;
445 445
446 if (!strlen(name))
447 return -ENODEV;
448
446 newprop = new_property(name, length, value, NULL); 449 newprop = new_property(name, length, value, NULL);
447 if (!newprop) 450 if (!newprop)
448 return -ENOMEM; 451 return -ENOMEM;
@@ -450,18 +453,11 @@ static int do_update_property(char *buf, size_t bufsize)
450 if (!strcmp(name, "slb-size") || !strcmp(name, "ibm,slb-size")) 453 if (!strcmp(name, "slb-size") || !strcmp(name, "ibm,slb-size"))
451 slb_set_size(*(int *)value); 454 slb_set_size(*(int *)value);
452 455
453 oldprop = of_find_property(np, name,NULL);
454 if (!oldprop) {
455 if (strlen(name))
456 return prom_add_property(np, newprop);
457 return -ENODEV;
458 }
459
460 upd_value.node = np; 456 upd_value.node = np;
461 upd_value.property = newprop; 457 upd_value.property = newprop;
462 pSeries_reconfig_notify(PSERIES_UPDATE_PROPERTY, &upd_value); 458 pSeries_reconfig_notify(PSERIES_UPDATE_PROPERTY, &upd_value);
463 459
464 rc = prom_update_property(np, newprop, oldprop); 460 rc = prom_update_property(np, newprop);
465 if (rc) 461 if (rc)
466 return rc; 462 return rc;
467 463
@@ -486,7 +482,7 @@ static int do_update_property(char *buf, size_t bufsize)
486 482
487 rc = pSeries_reconfig_notify(action, value); 483 rc = pSeries_reconfig_notify(action, value);
488 if (rc) { 484 if (rc) {
489 prom_update_property(np, oldprop, newprop); 485 prom_update_property(np, newprop);
490 return rc; 486 return rc;
491 } 487 }
492 } 488 }
diff --git a/drivers/of/base.c b/drivers/of/base.c
index eada3f4ef801..bc86ea2af668 100644
--- a/drivers/of/base.c
+++ b/drivers/of/base.c
@@ -1073,7 +1073,8 @@ int prom_remove_property(struct device_node *np, struct property *prop)
1073} 1073}
1074 1074
1075/* 1075/*
1076 * prom_update_property - Update a property in a node. 1076 * prom_update_property - Update a property in a node, if the property does
1077 * not exist, add it.
1077 * 1078 *
1078 * Note that we don't actually remove it, since we have given out 1079 * Note that we don't actually remove it, since we have given out
1079 * who-knows-how-many pointers to the data using get-property. 1080 * who-knows-how-many pointers to the data using get-property.
@@ -1081,13 +1082,19 @@ int prom_remove_property(struct device_node *np, struct property *prop)
1081 * and add the new property to the property list 1082 * and add the new property to the property list
1082 */ 1083 */
1083int prom_update_property(struct device_node *np, 1084int prom_update_property(struct device_node *np,
1084 struct property *newprop, 1085 struct property *newprop)
1085 struct property *oldprop)
1086{ 1086{
1087 struct property **next; 1087 struct property **next, *oldprop;
1088 unsigned long flags; 1088 unsigned long flags;
1089 int found = 0; 1089 int found = 0;
1090 1090
1091 if (!newprop->name)
1092 return -EINVAL;
1093
1094 oldprop = of_find_property(np, newprop->name, NULL);
1095 if (!oldprop)
1096 return prom_add_property(np, newprop);
1097
1091 write_lock_irqsave(&devtree_lock, flags); 1098 write_lock_irqsave(&devtree_lock, flags);
1092 next = &np->properties; 1099 next = &np->properties;
1093 while (*next) { 1100 while (*next) {
diff --git a/fs/proc/proc_devtree.c b/fs/proc/proc_devtree.c
index 927cbd115e53..df7dd08d4391 100644
--- a/fs/proc/proc_devtree.c
+++ b/fs/proc/proc_devtree.c
@@ -101,6 +101,11 @@ void proc_device_tree_update_prop(struct proc_dir_entry *pde,
101{ 101{
102 struct proc_dir_entry *ent; 102 struct proc_dir_entry *ent;
103 103
104 if (!oldprop) {
105 proc_device_tree_add_prop(pde, newprop);
106 return;
107 }
108
104 for (ent = pde->subdir; ent != NULL; ent = ent->next) 109 for (ent = pde->subdir; ent != NULL; ent = ent->next)
105 if (ent->data == oldprop) 110 if (ent->data == oldprop)
106 break; 111 break;
diff --git a/include/linux/of.h b/include/linux/of.h
index 2ec1083af7ff..b27c87191df2 100644
--- a/include/linux/of.h
+++ b/include/linux/of.h
@@ -260,8 +260,7 @@ extern int of_machine_is_compatible(const char *compat);
260extern int prom_add_property(struct device_node* np, struct property* prop); 260extern int prom_add_property(struct device_node* np, struct property* prop);
261extern int prom_remove_property(struct device_node *np, struct property *prop); 261extern int prom_remove_property(struct device_node *np, struct property *prop);
262extern int prom_update_property(struct device_node *np, 262extern int prom_update_property(struct device_node *np,
263 struct property *newprop, 263 struct property *newprop);
264 struct property *oldprop);
265 264
266#if defined(CONFIG_OF_DYNAMIC) 265#if defined(CONFIG_OF_DYNAMIC)
267/* For updating the device tree at runtime */ 266/* For updating the device tree at runtime */