diff options
author | Dong Aisheng <dong.aisheng@linaro.org> | 2012-07-11 01:16:37 -0400 |
---|---|---|
committer | Benjamin Herrenschmidt <benh@kernel.crashing.org> | 2012-07-11 01:26:51 -0400 |
commit | 475d0094293b51353e342d1198377967dbc48169 (patch) | |
tree | b10a01706dd433b93353600a00491ce62e385ec9 | |
parent | b416c9a10baae6a177b4f9ee858b8d309542fbef (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.c | 8 | ||||
-rw-r--r-- | arch/powerpc/platforms/pseries/mobility.c | 8 | ||||
-rw-r--r-- | arch/powerpc/platforms/pseries/reconfig.c | 16 | ||||
-rw-r--r-- | drivers/of/base.c | 15 | ||||
-rw-r--r-- | fs/proc/proc_devtree.c | 5 | ||||
-rw-r--r-- | include/linux/of.h | 3 |
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 | */ |
349 | static void __init disable_one_node(struct device_node *np, struct property *new) | 349 | static 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 | */ |
1083 | int prom_update_property(struct device_node *np, | 1084 | int 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); | |||
260 | extern int prom_add_property(struct device_node* np, struct property* prop); | 260 | extern int prom_add_property(struct device_node* np, struct property* prop); |
261 | extern int prom_remove_property(struct device_node *np, struct property *prop); | 261 | extern int prom_remove_property(struct device_node *np, struct property *prop); |
262 | extern int prom_update_property(struct device_node *np, | 262 | extern 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 */ |