Commit 475d0094 authored by Dong Aisheng's avatar Dong Aisheng Committed by Benjamin Herrenschmidt

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: default avatarGrant Likely <grant.likely@secretlab.ca>
Signed-off-by: default avatarDong Aisheng <dong.aisheng@linaro.org>
Acked-by: default avatarRob Herring <rob.herring@calxeda.com>
Signed-off-by: default avatarBenjamin Herrenschmidt <benh@kernel.crashing.org>
parent b416c9a1
...@@ -348,13 +348,7 @@ void __init p1022_ds_pic_init(void) ...@@ -348,13 +348,7 @@ void __init p1022_ds_pic_init(void)
*/ */
static void __init disable_one_node(struct device_node *np, struct property *new) static void __init disable_one_node(struct device_node *np, struct property *new)
{ {
struct property *old; prom_update_property(np, new);
old = of_find_property(np, new->name, NULL);
if (old)
prom_update_property(np, new, old);
else
prom_add_property(np, new);
} }
/* TRUE if there is a "video=fslfb" command-line parameter. */ /* TRUE if there is a "video=fslfb" command-line parameter. */
......
...@@ -67,7 +67,6 @@ static int update_dt_property(struct device_node *dn, struct property **prop, ...@@ -67,7 +67,6 @@ static int update_dt_property(struct device_node *dn, struct property **prop,
const char *name, u32 vd, char *value) const char *name, u32 vd, char *value)
{ {
struct property *new_prop = *prop; struct property *new_prop = *prop;
struct property *old_prop;
int more = 0; int more = 0;
/* A negative 'vd' value indicates that only part of the new property /* 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,12 +116,7 @@ static int update_dt_property(struct device_node *dn, struct property **prop,
} }
if (!more) { if (!more) {
old_prop = of_find_property(dn, new_prop->name, NULL); prom_update_property(dn, new_prop);
if (old_prop)
prom_update_property(dn, new_prop, old_prop);
else
prom_add_property(dn, new_prop);
new_prop = NULL; new_prop = NULL;
} }
......
...@@ -432,7 +432,7 @@ static int do_update_property(char *buf, size_t bufsize) ...@@ -432,7 +432,7 @@ static int do_update_property(char *buf, size_t bufsize)
unsigned char *value; unsigned char *value;
char *name, *end, *next_prop; char *name, *end, *next_prop;
int rc, length; int rc, length;
struct property *newprop, *oldprop; struct property *newprop;
buf = parse_node(buf, bufsize, &np); buf = parse_node(buf, bufsize, &np);
end = buf + bufsize; end = buf + bufsize;
...@@ -443,6 +443,9 @@ static int do_update_property(char *buf, size_t bufsize) ...@@ -443,6 +443,9 @@ static int do_update_property(char *buf, size_t bufsize)
if (!next_prop) if (!next_prop)
return -EINVAL; return -EINVAL;
if (!strlen(name))
return -ENODEV;
newprop = new_property(name, length, value, NULL); newprop = new_property(name, length, value, NULL);
if (!newprop) if (!newprop)
return -ENOMEM; return -ENOMEM;
...@@ -450,18 +453,11 @@ static int do_update_property(char *buf, size_t bufsize) ...@@ -450,18 +453,11 @@ static int do_update_property(char *buf, size_t bufsize)
if (!strcmp(name, "slb-size") || !strcmp(name, "ibm,slb-size")) if (!strcmp(name, "slb-size") || !strcmp(name, "ibm,slb-size"))
slb_set_size(*(int *)value); slb_set_size(*(int *)value);
oldprop = of_find_property(np, name,NULL);
if (!oldprop) {
if (strlen(name))
return prom_add_property(np, newprop);
return -ENODEV;
}
upd_value.node = np; upd_value.node = np;
upd_value.property = newprop; upd_value.property = newprop;
pSeries_reconfig_notify(PSERIES_UPDATE_PROPERTY, &upd_value); pSeries_reconfig_notify(PSERIES_UPDATE_PROPERTY, &upd_value);
rc = prom_update_property(np, newprop, oldprop); rc = prom_update_property(np, newprop);
if (rc) if (rc)
return rc; return rc;
...@@ -486,7 +482,7 @@ static int do_update_property(char *buf, size_t bufsize) ...@@ -486,7 +482,7 @@ static int do_update_property(char *buf, size_t bufsize)
rc = pSeries_reconfig_notify(action, value); rc = pSeries_reconfig_notify(action, value);
if (rc) { if (rc) {
prom_update_property(np, oldprop, newprop); prom_update_property(np, newprop);
return rc; return rc;
} }
} }
......
...@@ -1073,7 +1073,8 @@ int prom_remove_property(struct device_node *np, struct property *prop) ...@@ -1073,7 +1073,8 @@ int prom_remove_property(struct device_node *np, struct property *prop)
} }
/* /*
* prom_update_property - Update a property in a node. * prom_update_property - Update a property in a node, if the property does
* not exist, add it.
* *
* Note that we don't actually remove it, since we have given out * Note that we don't actually remove it, since we have given out
* who-knows-how-many pointers to the data using get-property. * 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,13 +1082,19 @@ int prom_remove_property(struct device_node *np, struct property *prop)
* and add the new property to the property list * and add the new property to the property list
*/ */
int prom_update_property(struct device_node *np, int prom_update_property(struct device_node *np,
struct property *newprop, struct property *newprop)
struct property *oldprop)
{ {
struct property **next; struct property **next, *oldprop;
unsigned long flags; unsigned long flags;
int found = 0; int found = 0;
if (!newprop->name)
return -EINVAL;
oldprop = of_find_property(np, newprop->name, NULL);
if (!oldprop)
return prom_add_property(np, newprop);
write_lock_irqsave(&devtree_lock, flags); write_lock_irqsave(&devtree_lock, flags);
next = &np->properties; next = &np->properties;
while (*next) { while (*next) {
......
...@@ -101,6 +101,11 @@ void proc_device_tree_update_prop(struct proc_dir_entry *pde, ...@@ -101,6 +101,11 @@ void proc_device_tree_update_prop(struct proc_dir_entry *pde,
{ {
struct proc_dir_entry *ent; struct proc_dir_entry *ent;
if (!oldprop) {
proc_device_tree_add_prop(pde, newprop);
return;
}
for (ent = pde->subdir; ent != NULL; ent = ent->next) for (ent = pde->subdir; ent != NULL; ent = ent->next)
if (ent->data == oldprop) if (ent->data == oldprop)
break; break;
......
...@@ -260,8 +260,7 @@ extern int of_machine_is_compatible(const char *compat); ...@@ -260,8 +260,7 @@ extern int of_machine_is_compatible(const char *compat);
extern int prom_add_property(struct device_node* np, struct property* prop); extern int prom_add_property(struct device_node* np, struct property* prop);
extern int prom_remove_property(struct device_node *np, struct property *prop); extern int prom_remove_property(struct device_node *np, struct property *prop);
extern int prom_update_property(struct device_node *np, extern int prom_update_property(struct device_node *np,
struct property *newprop, struct property *newprop);
struct property *oldprop);
#if defined(CONFIG_OF_DYNAMIC) #if defined(CONFIG_OF_DYNAMIC)
/* For updating the device tree at runtime */ /* For updating the device tree at runtime */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment