aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/platforms/pseries/reconfig.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/powerpc/platforms/pseries/reconfig.c')
-rw-r--r--arch/powerpc/platforms/pseries/reconfig.c68
1 files changed, 4 insertions, 64 deletions
diff --git a/arch/powerpc/platforms/pseries/reconfig.c b/arch/powerpc/platforms/pseries/reconfig.c
index f99f1ca8035b..720a0cc2e69f 100644
--- a/arch/powerpc/platforms/pseries/reconfig.c
+++ b/arch/powerpc/platforms/pseries/reconfig.c
@@ -16,11 +16,11 @@
16#include <linux/notifier.h> 16#include <linux/notifier.h>
17#include <linux/proc_fs.h> 17#include <linux/proc_fs.h>
18#include <linux/slab.h> 18#include <linux/slab.h>
19#include <linux/of.h>
19 20
20#include <asm/prom.h> 21#include <asm/prom.h>
21#include <asm/machdep.h> 22#include <asm/machdep.h>
22#include <asm/uaccess.h> 23#include <asm/uaccess.h>
23#include <asm/pSeries_reconfig.h>
24#include <asm/mmu.h> 24#include <asm/mmu.h>
25 25
26/** 26/**
@@ -55,28 +55,6 @@ static struct device_node *derive_parent(const char *path)
55 return parent; 55 return parent;
56} 56}
57 57
58static BLOCKING_NOTIFIER_HEAD(pSeries_reconfig_chain);
59
60int pSeries_reconfig_notifier_register(struct notifier_block *nb)
61{
62 return blocking_notifier_chain_register(&pSeries_reconfig_chain, nb);
63}
64EXPORT_SYMBOL_GPL(pSeries_reconfig_notifier_register);
65
66void pSeries_reconfig_notifier_unregister(struct notifier_block *nb)
67{
68 blocking_notifier_chain_unregister(&pSeries_reconfig_chain, nb);
69}
70EXPORT_SYMBOL_GPL(pSeries_reconfig_notifier_unregister);
71
72int pSeries_reconfig_notify(unsigned long action, void *p)
73{
74 int err = blocking_notifier_call_chain(&pSeries_reconfig_chain,
75 action, p);
76
77 return notifier_to_errno(err);
78}
79
80static int pSeries_reconfig_add_node(const char *path, struct property *proplist) 58static int pSeries_reconfig_add_node(const char *path, struct property *proplist)
81{ 59{
82 struct device_node *np; 60 struct device_node *np;
@@ -100,13 +78,12 @@ static int pSeries_reconfig_add_node(const char *path, struct property *proplist
100 goto out_err; 78 goto out_err;
101 } 79 }
102 80
103 err = pSeries_reconfig_notify(PSERIES_RECONFIG_ADD, np); 81 err = of_attach_node(np);
104 if (err) { 82 if (err) {
105 printk(KERN_ERR "Failed to add device node %s\n", path); 83 printk(KERN_ERR "Failed to add device node %s\n", path);
106 goto out_err; 84 goto out_err;
107 } 85 }
108 86
109 of_attach_node(np);
110 of_node_put(np->parent); 87 of_node_put(np->parent);
111 88
112 return 0; 89 return 0;
@@ -134,9 +111,7 @@ static int pSeries_reconfig_remove_node(struct device_node *np)
134 return -EBUSY; 111 return -EBUSY;
135 } 112 }
136 113
137 pSeries_reconfig_notify(PSERIES_RECONFIG_REMOVE, np);
138 of_detach_node(np); 114 of_detach_node(np);
139
140 of_node_put(parent); 115 of_node_put(parent);
141 of_node_put(np); /* Must decrement the refcount */ 116 of_node_put(np); /* Must decrement the refcount */
142 return 0; 117 return 0;
@@ -381,10 +356,9 @@ static int do_remove_property(char *buf, size_t bufsize)
381static int do_update_property(char *buf, size_t bufsize) 356static int do_update_property(char *buf, size_t bufsize)
382{ 357{
383 struct device_node *np; 358 struct device_node *np;
384 struct pSeries_reconfig_prop_update upd_value;
385 unsigned char *value; 359 unsigned char *value;
386 char *name, *end, *next_prop; 360 char *name, *end, *next_prop;
387 int rc, length; 361 int length;
388 struct property *newprop; 362 struct property *newprop;
389 buf = parse_node(buf, bufsize, &np); 363 buf = parse_node(buf, bufsize, &np);
390 end = buf + bufsize; 364 end = buf + bufsize;
@@ -406,41 +380,7 @@ static int do_update_property(char *buf, size_t bufsize)
406 if (!strcmp(name, "slb-size") || !strcmp(name, "ibm,slb-size")) 380 if (!strcmp(name, "slb-size") || !strcmp(name, "ibm,slb-size"))
407 slb_set_size(*(int *)value); 381 slb_set_size(*(int *)value);
408 382
409 upd_value.node = np; 383 return prom_update_property(np, newprop);
410 upd_value.property = newprop;
411 pSeries_reconfig_notify(PSERIES_UPDATE_PROPERTY, &upd_value);
412
413 rc = prom_update_property(np, newprop);
414 if (rc)
415 return rc;
416
417 /* For memory under the ibm,dynamic-reconfiguration-memory node
418 * of the device tree, adding and removing memory is just an update
419 * to the ibm,dynamic-memory property instead of adding/removing a
420 * memory node in the device tree. For these cases we still need to
421 * involve the notifier chain.
422 */
423 if (!strcmp(name, "ibm,dynamic-memory")) {
424 int action;
425
426 next_prop = parse_next_property(next_prop, end, &name,
427 &length, &value);
428 if (!next_prop)
429 return -EINVAL;
430
431 if (!strcmp(name, "add"))
432 action = PSERIES_DRCONF_MEM_ADD;
433 else
434 action = PSERIES_DRCONF_MEM_REMOVE;
435
436 rc = pSeries_reconfig_notify(action, value);
437 if (rc) {
438 prom_update_property(np, newprop);
439 return rc;
440 }
441 }
442
443 return 0;
444} 384}
445 385
446/** 386/**