14 #include <linux/kernel.h>
18 #include <linux/slab.h>
21 #include <asm/machdep.h>
22 #include <asm/uaccess.h>
31 #ifdef CONFIG_PROC_DEVICETREE
35 static void add_node_proc_entries(
struct device_node *np)
44 static void remove_node_proc_entries(
struct device_node *np)
57 static void add_node_proc_entries(
struct device_node *np)
62 static void remove_node_proc_entries(
struct device_node *np)
79 char *parent_path =
"/";
80 size_t parent_path_len =
strrchr(path,
'/') - path + 1;
86 if (
strrchr(path,
'/') != path) {
90 strlcpy(parent_path, path, parent_path_len);
95 if (
strcmp(parent_path,
"/"))
119 return notifier_to_errno(err);
122 static int pSeries_reconfig_add_node(
const char *path,
struct property *proplist)
136 of_node_set_flag(np, OF_DYNAMIC);
137 kref_init(&np->
kref);
139 np->
parent = derive_parent(path);
141 err = PTR_ERR(np->
parent);
153 add_node_proc_entries(np);
168 static int pSeries_reconfig_remove_node(
struct device_node *np)
182 remove_node_proc_entries(np);
198 static void release_prop_list(
const struct property *prop)
201 for (; prop; prop =
next) {
222 static char * parse_next_property(
char *
buf,
char *
end,
char **
name,
int *
length,
223 unsigned char **
value)
251 if (*tmp !=
' ' || ++tmp >= end) {
265 else if (tmp < end && *tmp !=
' ' && *tmp !=
'\0') {
276 static struct property *new_property(
const char *name,
const int length,
277 const unsigned char *value,
struct property *last)
290 memcpy(new->value, value, length);
291 *(((
char *)new->value) +
length) = 0;
303 static int do_add_node(
char *buf,
size_t bufsize)
308 unsigned char*
value;
326 (buf = parse_next_property(buf, end, &name, &length, &value))) {
329 prop = new_property(name, length, value, last);
341 rv = pSeries_reconfig_add_node(path, prop);
345 release_prop_list(prop);
349 static int do_remove_node(
char *buf)
355 rv = pSeries_reconfig_remove_node(node);
361 static char *parse_node(
char *buf,
size_t bufsize,
struct device_node **npp)
381 static int do_add_property(
char *buf,
size_t bufsize)
385 unsigned char *
value;
389 buf = parse_node(buf, bufsize, &np);
394 if (parse_next_property(buf, end, &name, &length, &value) ==
NULL)
397 prop = new_property(name, length, value,
NULL);
406 static int do_remove_property(
char *buf,
size_t bufsize)
411 buf = parse_node(buf, bufsize, &np);
428 static int do_update_property(
char *buf,
size_t bufsize)
431 struct pSeries_reconfig_prop_update upd_value;
432 unsigned char *
value;
436 buf = parse_node(buf, bufsize, &np);
442 next_prop = parse_next_property(buf, end, &name, &length, &value);
449 newprop = new_property(name, length, value,
NULL);
453 if (!
strcmp(name,
"slb-size") || !
strcmp(name,
"ibm,slb-size"))
457 upd_value.property = newprop;
470 if (!
strcmp(name,
"ibm,dynamic-memory")) {
473 next_prop = parse_next_property(next_prop, end, &name,
479 action = PSERIES_DRCONF_MEM_ADD;
481 action = PSERIES_DRCONF_MEM_REMOVE;
531 if (!
strcmp(kbuf,
"add_node"))
532 rv = do_add_node(tmp, count - (tmp - kbuf));
533 else if (!
strcmp(kbuf,
"remove_node"))
534 rv = do_remove_node(tmp);
535 else if (!
strcmp(kbuf,
"add_property"))
536 rv = do_add_property(tmp, count - (tmp - kbuf));
537 else if (!
strcmp(kbuf,
"remove_property"))
538 rv = do_remove_property(tmp, count - (tmp - kbuf));
539 else if (!
strcmp(kbuf,
"update_property"))
540 rv = do_update_property(tmp, count - (tmp - kbuf));
545 return rv ? rv :
count;
554 static int proc_ppc64_create_ofdt(
void)
558 if (!machine_is(pseries))
561 ent = proc_create(
"powerpc/ofdt",
S_IWUSR,
NULL, &ofdt_fops);