diff options
author | Dave C Boutcher <sleddog@us.ibm.com> | 2006-01-12 17:10:22 -0500 |
---|---|---|
committer | Paul Mackerras <paulus@samba.org> | 2006-01-13 05:12:41 -0500 |
commit | 610d91511f99f0a8325ad78fb7259c454b23e65a (patch) | |
tree | 7b391f12c8f9eb2d6aa14c10e2302faa57c50e7b /arch | |
parent | ecaa8b0ff326920c8a89d748382e1c1d8812676c (diff) |
[PATCH] powerpc: Add support for changing properties from userspace
Add support to reconfigure the device tree through the existing
proc filesystem interface. Add "add_property", "remove_property",
and "update_property" commands to the existing interface.
Signed-off-by: Dave Boutcher <sleddog@us.ibm.com>
Signed-off-by: Paul Mackerras <paulus@samba.org>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/powerpc/platforms/pseries/reconfig.c | 100 |
1 files changed, 100 insertions, 0 deletions
diff --git a/arch/powerpc/platforms/pseries/reconfig.c b/arch/powerpc/platforms/pseries/reconfig.c index d8864164dbe8..86cfa6ecdcf3 100644 --- a/arch/powerpc/platforms/pseries/reconfig.c +++ b/arch/powerpc/platforms/pseries/reconfig.c | |||
@@ -350,6 +350,100 @@ static int do_remove_node(char *buf) | |||
350 | return rv; | 350 | return rv; |
351 | } | 351 | } |
352 | 352 | ||
353 | static char *parse_node(char *buf, size_t bufsize, struct device_node **npp) | ||
354 | { | ||
355 | char *handle_str; | ||
356 | phandle handle; | ||
357 | *npp = NULL; | ||
358 | |||
359 | handle_str = buf; | ||
360 | |||
361 | buf = strchr(buf, ' '); | ||
362 | if (!buf) | ||
363 | return NULL; | ||
364 | *buf = '\0'; | ||
365 | buf++; | ||
366 | |||
367 | handle = simple_strtoul(handle_str, NULL, 10); | ||
368 | |||
369 | *npp = of_find_node_by_phandle(handle); | ||
370 | return buf; | ||
371 | } | ||
372 | |||
373 | static int do_add_property(char *buf, size_t bufsize) | ||
374 | { | ||
375 | struct property *prop = NULL; | ||
376 | struct device_node *np; | ||
377 | unsigned char *value; | ||
378 | char *name, *end; | ||
379 | int length; | ||
380 | end = buf + bufsize; | ||
381 | buf = parse_node(buf, bufsize, &np); | ||
382 | |||
383 | if (!np) | ||
384 | return -ENODEV; | ||
385 | |||
386 | if (parse_next_property(buf, end, &name, &length, &value) == NULL) | ||
387 | return -EINVAL; | ||
388 | |||
389 | prop = new_property(name, length, value, NULL); | ||
390 | if (!prop) | ||
391 | return -ENOMEM; | ||
392 | |||
393 | prom_add_property(np, prop); | ||
394 | |||
395 | return 0; | ||
396 | } | ||
397 | |||
398 | static int do_remove_property(char *buf, size_t bufsize) | ||
399 | { | ||
400 | struct device_node *np; | ||
401 | char *tmp; | ||
402 | struct property *prop; | ||
403 | buf = parse_node(buf, bufsize, &np); | ||
404 | |||
405 | if (!np) | ||
406 | return -ENODEV; | ||
407 | |||
408 | tmp = strchr(buf,' '); | ||
409 | if (tmp) | ||
410 | *tmp = '\0'; | ||
411 | |||
412 | if (strlen(buf) == 0) | ||
413 | return -EINVAL; | ||
414 | |||
415 | prop = of_find_property(np, buf, NULL); | ||
416 | |||
417 | return prom_remove_property(np, prop); | ||
418 | } | ||
419 | |||
420 | static int do_update_property(char *buf, size_t bufsize) | ||
421 | { | ||
422 | struct device_node *np; | ||
423 | unsigned char *value; | ||
424 | char *name, *end; | ||
425 | int length; | ||
426 | struct property *newprop, *oldprop; | ||
427 | buf = parse_node(buf, bufsize, &np); | ||
428 | end = buf + bufsize; | ||
429 | |||
430 | if (!np) | ||
431 | return -ENODEV; | ||
432 | |||
433 | if (parse_next_property(buf, end, &name, &length, &value) == NULL) | ||
434 | return -EINVAL; | ||
435 | |||
436 | newprop = new_property(name, length, value, NULL); | ||
437 | if (!newprop) | ||
438 | return -ENOMEM; | ||
439 | |||
440 | oldprop = of_find_property(np, name,NULL); | ||
441 | if (!oldprop) | ||
442 | return -ENODEV; | ||
443 | |||
444 | return prom_update_property(np, newprop, oldprop); | ||
445 | } | ||
446 | |||
353 | /** | 447 | /** |
354 | * ofdt_write - perform operations on the Open Firmware device tree | 448 | * ofdt_write - perform operations on the Open Firmware device tree |
355 | * | 449 | * |
@@ -392,6 +486,12 @@ static ssize_t ofdt_write(struct file *file, const char __user *buf, size_t coun | |||
392 | rv = do_add_node(tmp, count - (tmp - kbuf)); | 486 | rv = do_add_node(tmp, count - (tmp - kbuf)); |
393 | else if (!strcmp(kbuf, "remove_node")) | 487 | else if (!strcmp(kbuf, "remove_node")) |
394 | rv = do_remove_node(tmp); | 488 | rv = do_remove_node(tmp); |
489 | else if (!strcmp(kbuf, "add_property")) | ||
490 | rv = do_add_property(tmp, count - (tmp - kbuf)); | ||
491 | else if (!strcmp(kbuf, "remove_property")) | ||
492 | rv = do_remove_property(tmp, count - (tmp - kbuf)); | ||
493 | else if (!strcmp(kbuf, "update_property")) | ||
494 | rv = do_update_property(tmp, count - (tmp - kbuf)); | ||
395 | else | 495 | else |
396 | rv = -EINVAL; | 496 | rv = -EINVAL; |
397 | out: | 497 | out: |