aboutsummaryrefslogtreecommitdiff
path: root/arch/powerpc/platforms/pseries
diff options
context:
space:
mode:
Diffstat (limited to 'arch/powerpc/platforms/pseries')
-rw-r--r--arch/powerpc/platforms/pseries/lpar.c4
-rw-r--r--arch/powerpc/platforms/pseries/reconfig.c100
-rw-r--r--arch/powerpc/platforms/pseries/setup.c20
3 files changed, 111 insertions, 13 deletions
diff --git a/arch/powerpc/platforms/pseries/lpar.c b/arch/powerpc/platforms/pseries/lpar.c
index 1fe445ab78a..8952528d31a 100644
--- a/arch/powerpc/platforms/pseries/lpar.c
+++ b/arch/powerpc/platforms/pseries/lpar.c
@@ -254,11 +254,11 @@ out:
void vpa_init(int cpu)
{
int hwcpu = get_hard_smp_processor_id(cpu);
- unsigned long vpa = __pa(&paca[cpu].lppaca);
+ unsigned long vpa = __pa(&lppaca[cpu]);
long ret;
if (cpu_has_feature(CPU_FTR_ALTIVEC))
- paca[cpu].lppaca.vmxregs_in_use = 1;
+ lppaca[cpu].vmxregs_in_use = 1;
ret = register_vpa(hwcpu, vpa);
diff --git a/arch/powerpc/platforms/pseries/reconfig.c b/arch/powerpc/platforms/pseries/reconfig.c
index d8864164dbe..86cfa6ecdcf 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)
return rv;
}
+static char *parse_node(char *buf, size_t bufsize, struct device_node **npp)
+{
+ char *handle_str;
+ phandle handle;
+ *npp = NULL;
+
+ handle_str = buf;
+
+ buf = strchr(buf, ' ');
+ if (!buf)
+ return NULL;
+ *buf = '\0';
+ buf++;
+
+ handle = simple_strtoul(handle_str, NULL, 10);
+
+ *npp = of_find_node_by_phandle(handle);
+ return buf;
+}
+
+static int do_add_property(char *buf, size_t bufsize)
+{
+ struct property *prop = NULL;
+ struct device_node *np;
+ unsigned char *value;
+ char *name, *end;
+ int length;
+ end = buf + bufsize;
+ buf = parse_node(buf, bufsize, &np);
+
+ if (!np)
+ return -ENODEV;
+
+ if (parse_next_property(buf, end, &name, &length, &value) == NULL)
+ return -EINVAL;
+
+ prop = new_property(name, length, value, NULL);
+ if (!prop)
+ return -ENOMEM;
+
+ prom_add_property(np, prop);
+
+ return 0;
+}
+
+static int do_remove_property(char *buf, size_t bufsize)
+{
+ struct device_node *np;
+ char *tmp;
+ struct property *prop;
+ buf = parse_node(buf, bufsize, &np);
+
+ if (!np)
+ return -ENODEV;
+
+ tmp = strchr(buf,' ');
+ if (tmp)
+ *tmp = '\0';
+
+ if (strlen(buf) == 0)
+ return -EINVAL;
+
+ prop = of_find_property(np, buf, NULL);
+
+ return prom_remove_property(np, prop);
+}
+
+static int do_update_property(char *buf, size_t bufsize)
+{
+ struct device_node *np;
+ unsigned char *value;
+ char *name, *end;
+ int length;
+ struct property *newprop, *oldprop;
+ buf = parse_node(buf, bufsize, &np);
+ end = buf + bufsize;
+
+ if (!np)
+ return -ENODEV;
+
+ if (parse_next_property(buf, end, &name, &length, &value) == NULL)
+ return -EINVAL;
+
+ newprop = new_property(name, length, value, NULL);
+ if (!newprop)
+ return -ENOMEM;
+
+ oldprop = of_find_property(np, name,NULL);
+ if (!oldprop)
+ return -ENODEV;
+
+ return prom_update_property(np, newprop, oldprop);
+}
+
/**
* ofdt_write - perform operations on the Open Firmware device tree
*
@@ -392,6 +486,12 @@ static ssize_t ofdt_write(struct file *file, const char __user *buf, size_t coun
rv = do_add_node(tmp, count - (tmp - kbuf));
else if (!strcmp(kbuf, "remove_node"))
rv = do_remove_node(tmp);
+ else if (!strcmp(kbuf, "add_property"))
+ rv = do_add_property(tmp, count - (tmp - kbuf));
+ else if (!strcmp(kbuf, "remove_property"))
+ rv = do_remove_property(tmp, count - (tmp - kbuf));
+ else if (!strcmp(kbuf, "update_property"))
+ rv = do_update_property(tmp, count - (tmp - kbuf));
else
rv = -EINVAL;
out:
diff --git a/arch/powerpc/platforms/pseries/setup.c b/arch/powerpc/platforms/pseries/setup.c
index 68b7f086d63..da6cebaf72c 100644
--- a/arch/powerpc/platforms/pseries/setup.c
+++ b/arch/powerpc/platforms/pseries/setup.c
@@ -190,7 +190,7 @@ static void pseries_lpar_enable_pmcs(void)
/* instruct hypervisor to maintain PMCs */
if (firmware_has_feature(FW_FEATURE_SPLPAR))
- get_paca()->lppaca.pmcregs_in_use = 1;
+ get_lppaca()->pmcregs_in_use = 1;
}
static void __init pSeries_setup_arch(void)
@@ -234,7 +234,7 @@ static void __init pSeries_setup_arch(void)
/* Choose an idle loop */
if (firmware_has_feature(FW_FEATURE_SPLPAR)) {
vpa_init(boot_cpuid);
- if (get_paca()->lppaca.shared_proc) {
+ if (get_lppaca()->shared_proc) {
printk(KERN_INFO "Using shared processor idle loop\n");
ppc_md.idle_loop = pseries_shared_idle;
} else {
@@ -444,10 +444,10 @@ DECLARE_PER_CPU(unsigned long, smt_snooze_delay);
static inline void dedicated_idle_sleep(unsigned int cpu)
{
- struct paca_struct *ppaca = &paca[cpu ^ 1];
+ struct lppaca *plppaca = &lppaca[cpu ^ 1];
/* Only sleep if the other thread is not idle */
- if (!(ppaca->lppaca.idle)) {
+ if (!(plppaca->idle)) {
local_irq_disable();
/*
@@ -480,7 +480,6 @@ static inline void dedicated_idle_sleep(unsigned int cpu)
static void pseries_dedicated_idle(void)
{
- struct paca_struct *lpaca = get_paca();
unsigned int cpu = smp_processor_id();
unsigned long start_snooze;
unsigned long *smt_snooze_delay = &__get_cpu_var(smt_snooze_delay);
@@ -491,7 +490,7 @@ static void pseries_dedicated_idle(void)
* Indicate to the HV that we are idle. Now would be
* a good time to find other work to dispatch.
*/
- lpaca->lppaca.idle = 1;
+ get_lppaca()->idle = 1;
if (!need_resched()) {
start_snooze = get_tb() +
@@ -518,7 +517,7 @@ static void pseries_dedicated_idle(void)
HMT_medium();
}
- lpaca->lppaca.idle = 0;
+ get_lppaca()->idle = 0;
ppc64_runlatch_on();
preempt_enable_no_resched();
@@ -532,7 +531,6 @@ static void pseries_dedicated_idle(void)
static void pseries_shared_idle(void)
{
- struct paca_struct *lpaca = get_paca();
unsigned int cpu = smp_processor_id();
while (1) {
@@ -540,7 +538,7 @@ static void pseries_shared_idle(void)
* Indicate to the HV that we are idle. Now would be
* a good time to find other work to dispatch.
*/
- lpaca->lppaca.idle = 1;
+ get_lppaca()->idle = 1;
while (!need_resched() && !cpu_is_offline(cpu)) {
local_irq_disable();
@@ -564,7 +562,7 @@ static void pseries_shared_idle(void)
HMT_medium();
}
- lpaca->lppaca.idle = 0;
+ get_lppaca()->idle = 0;
ppc64_runlatch_on();
preempt_enable_no_resched();
@@ -588,7 +586,7 @@ static void pseries_kexec_cpu_down(int crash_shutdown, int secondary)
{
/* Don't risk a hypervisor call if we're crashing */
if (!crash_shutdown) {
- unsigned long vpa = __pa(&get_paca()->lppaca);
+ unsigned long vpa = __pa(get_lppaca());
if (unregister_vpa(hard_smp_processor_id(), vpa)) {
printk("VPA deregistration of cpu %u (hw_cpu_id %d) "