aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/sparc/kernel/prom.c53
-rw-r--r--arch/sparc64/kernel/prom.c53
-rw-r--r--include/asm-sparc/prom.h8
-rw-r--r--include/asm-sparc64/prom.h8
4 files changed, 122 insertions, 0 deletions
diff --git a/arch/sparc/kernel/prom.c b/arch/sparc/kernel/prom.c
index 63b2b9bd778e..f3f53f2e0e1e 100644
--- a/arch/sparc/kernel/prom.c
+++ b/arch/sparc/kernel/prom.c
@@ -27,6 +27,11 @@
27 27
28static struct device_node *allnodes; 28static struct device_node *allnodes;
29 29
30/* use when traversing tree through the allnext, child, sibling,
31 * or parent members of struct device_node.
32 */
33static DEFINE_RWLOCK(devtree_lock);
34
30int of_device_is_compatible(struct device_node *device, const char *compat) 35int of_device_is_compatible(struct device_node *device, const char *compat)
31{ 36{
32 const char* cp; 37 const char* cp;
@@ -185,6 +190,54 @@ int of_getintprop_default(struct device_node *np, const char *name, int def)
185} 190}
186EXPORT_SYMBOL(of_getintprop_default); 191EXPORT_SYMBOL(of_getintprop_default);
187 192
193int of_set_property(struct device_node *dp, const char *name, void *val, int len)
194{
195 struct property **prevp;
196 void *new_val;
197 int err;
198
199 new_val = kmalloc(len, GFP_KERNEL);
200 if (!new_val)
201 return -ENOMEM;
202
203 memcpy(new_val, val, len);
204
205 err = -ENODEV;
206
207 write_lock(&devtree_lock);
208 prevp = &dp->properties;
209 while (*prevp) {
210 struct property *prop = *prevp;
211
212 if (!strcmp(prop->name, name)) {
213 void *old_val = prop->value;
214 int ret;
215
216 ret = prom_setprop(dp->node, name, val, len);
217 err = -EINVAL;
218 if (ret >= 0) {
219 prop->value = new_val;
220 prop->length = len;
221
222 if (OF_IS_DYNAMIC(prop))
223 kfree(old_val);
224
225 OF_MARK_DYNAMIC(prop);
226
227 err = 0;
228 }
229 break;
230 }
231 prevp = &(*prevp)->next;
232 }
233 write_unlock(&devtree_lock);
234
235 /* XXX Upate procfs if necessary... */
236
237 return err;
238}
239EXPORT_SYMBOL(of_set_property);
240
188static unsigned int prom_early_allocated; 241static unsigned int prom_early_allocated;
189 242
190static void * __init prom_early_alloc(unsigned long size) 243static void * __init prom_early_alloc(unsigned long size)
diff --git a/arch/sparc64/kernel/prom.c b/arch/sparc64/kernel/prom.c
index e9d703eea806..c62fd3e7a0f8 100644
--- a/arch/sparc64/kernel/prom.c
+++ b/arch/sparc64/kernel/prom.c
@@ -27,6 +27,11 @@
27 27
28static struct device_node *allnodes; 28static struct device_node *allnodes;
29 29
30/* use when traversing tree through the allnext, child, sibling,
31 * or parent members of struct device_node.
32 */
33static DEFINE_RWLOCK(devtree_lock);
34
30int of_device_is_compatible(struct device_node *device, const char *compat) 35int of_device_is_compatible(struct device_node *device, const char *compat)
31{ 36{
32 const char* cp; 37 const char* cp;
@@ -185,6 +190,54 @@ int of_getintprop_default(struct device_node *np, const char *name, int def)
185} 190}
186EXPORT_SYMBOL(of_getintprop_default); 191EXPORT_SYMBOL(of_getintprop_default);
187 192
193int of_set_property(struct device_node *dp, const char *name, void *val, int len)
194{
195 struct property **prevp;
196 void *new_val;
197 int err;
198
199 new_val = kmalloc(len, GFP_KERNEL);
200 if (!new_val)
201 return -ENOMEM;
202
203 memcpy(new_val, val, len);
204
205 err = -ENODEV;
206
207 write_lock(&devtree_lock);
208 prevp = &dp->properties;
209 while (*prevp) {
210 struct property *prop = *prevp;
211
212 if (!strcmp(prop->name, name)) {
213 void *old_val = prop->value;
214 int ret;
215
216 ret = prom_setprop(dp->node, name, val, len);
217 err = -EINVAL;
218 if (ret >= 0) {
219 prop->value = new_val;
220 prop->length = len;
221
222 if (OF_IS_DYNAMIC(prop))
223 kfree(old_val);
224
225 OF_MARK_DYNAMIC(prop);
226
227 err = 0;
228 }
229 break;
230 }
231 prevp = &(*prevp)->next;
232 }
233 write_unlock(&devtree_lock);
234
235 /* XXX Upate procfs if necessary... */
236
237 return err;
238}
239EXPORT_SYMBOL(of_set_property);
240
188static unsigned int prom_early_allocated; 241static unsigned int prom_early_allocated;
189 242
190static void * __init prom_early_alloc(unsigned long size) 243static void * __init prom_early_alloc(unsigned long size)
diff --git a/include/asm-sparc/prom.h b/include/asm-sparc/prom.h
index c5e3d26eabd3..e9b8047470fe 100644
--- a/include/asm-sparc/prom.h
+++ b/include/asm-sparc/prom.h
@@ -35,6 +35,7 @@ struct property {
35 int length; 35 int length;
36 void *value; 36 void *value;
37 struct property *next; 37 struct property *next;
38 unsigned long _flags;
38}; 39};
39 40
40struct device_node { 41struct device_node {
@@ -60,6 +61,12 @@ struct device_node {
60 void *data; 61 void *data;
61}; 62};
62 63
64/* flag descriptions */
65#define OF_DYNAMIC 1 /* node and properties were allocated via kmalloc */
66
67#define OF_IS_DYNAMIC(x) test_bit(OF_DYNAMIC, &x->_flags)
68#define OF_MARK_DYNAMIC(x) set_bit(OF_DYNAMIC, &x->_flags)
69
63static inline void set_node_proc_entry(struct device_node *dn, struct proc_dir_entry *de) 70static inline void set_node_proc_entry(struct device_node *dn, struct proc_dir_entry *de)
64{ 71{
65 dn->pde = de; 72 dn->pde = de;
@@ -88,6 +95,7 @@ extern struct property *of_find_property(struct device_node *np,
88extern int of_device_is_compatible(struct device_node *device, const char *); 95extern int of_device_is_compatible(struct device_node *device, const char *);
89extern void *of_get_property(struct device_node *node, const char *name, 96extern void *of_get_property(struct device_node *node, const char *name,
90 int *lenp); 97 int *lenp);
98extern int of_set_property(struct device_node *node, const char *name, void *val, int len);
91extern int of_getintprop_default(struct device_node *np, 99extern int of_getintprop_default(struct device_node *np,
92 const char *name, 100 const char *name,
93 int def); 101 int def);
diff --git a/include/asm-sparc64/prom.h b/include/asm-sparc64/prom.h
index 6d1556c0c263..c8022a337380 100644
--- a/include/asm-sparc64/prom.h
+++ b/include/asm-sparc64/prom.h
@@ -35,6 +35,7 @@ struct property {
35 int length; 35 int length;
36 void *value; 36 void *value;
37 struct property *next; 37 struct property *next;
38 unsigned long _flags;
38}; 39};
39 40
40struct device_node { 41struct device_node {
@@ -60,6 +61,12 @@ struct device_node {
60 void *data; 61 void *data;
61}; 62};
62 63
64/* flag descriptions */
65#define OF_DYNAMIC 1 /* node and properties were allocated via kmalloc */
66
67#define OF_IS_DYNAMIC(x) test_bit(OF_DYNAMIC, &x->_flags)
68#define OF_MARK_DYNAMIC(x) set_bit(OF_DYNAMIC, &x->_flags)
69
63static inline void set_node_proc_entry(struct device_node *dn, struct proc_dir_entry *de) 70static inline void set_node_proc_entry(struct device_node *dn, struct proc_dir_entry *de)
64{ 71{
65 dn->pde = de; 72 dn->pde = de;
@@ -88,6 +95,7 @@ extern struct property *of_find_property(struct device_node *np,
88extern int of_device_is_compatible(struct device_node *device, const char *); 95extern int of_device_is_compatible(struct device_node *device, const char *);
89extern void *of_get_property(struct device_node *node, const char *name, 96extern void *of_get_property(struct device_node *node, const char *name,
90 int *lenp); 97 int *lenp);
98extern int of_set_property(struct device_node *node, const char *name, void *val, int len);
91extern int of_getintprop_default(struct device_node *np, 99extern int of_getintprop_default(struct device_node *np,
92 const char *name, 100 const char *name,
93 int def); 101 int def);