llseek: automatically add .llseek fop
[linux-2.6.git] / arch / powerpc / platforms / pseries / reconfig.c
index 7637bd3..1de2cbb 100644 (file)
 #include <linux/kref.h>
 #include <linux/notifier.h>
 #include <linux/proc_fs.h>
+#include <linux/slab.h>
 
 #include <asm/prom.h>
 #include <asm/machdep.h>
 #include <asm/uaccess.h>
 #include <asm/pSeries_reconfig.h>
+#include <asm/mmu.h>
 
 
 
@@ -95,7 +97,7 @@ static struct device_node *derive_parent(const char *path)
        return parent;
 }
 
-static BLOCKING_NOTIFIER_HEAD(pSeries_reconfig_chain);
+BLOCKING_NOTIFIER_HEAD(pSeries_reconfig_chain);
 
 int pSeries_reconfig_notifier_register(struct notifier_block *nb)
 {
@@ -116,12 +118,10 @@ static int pSeries_reconfig_add_node(const char *path, struct property *proplist
        if (!np)
                goto out_err;
 
-       np->full_name = kmalloc(strlen(path) + 1, GFP_KERNEL);
+       np->full_name = kstrdup(path, GFP_KERNEL);
        if (!np->full_name)
                goto out_err;
 
-       strcpy(np->full_name, path);
-
        np->properties = proplist;
        of_node_set_flag(np, OF_DYNAMIC);
        kref_init(&np->kref);
@@ -183,7 +183,7 @@ static int pSeries_reconfig_remove_node(struct device_node *np)
 }
 
 /*
- * /proc/ppc64/ofdt - yucky binary interface for adding and removing
+ * /proc/powerpc/ofdt - yucky binary interface for adding and removing
  * OF device nodes.  Should be deprecated as soon as we get an
  * in-kernel wrapper for the RTAS ibm,configure-connector call.
  */
@@ -439,9 +439,15 @@ static int do_update_property(char *buf, size_t bufsize)
        if (!newprop)
                return -ENOMEM;
 
+       if (!strcmp(name, "slb-size") || !strcmp(name, "ibm,slb-size"))
+               slb_set_size(*(int *)value);
+
        oldprop = of_find_property(np, name,NULL);
-       if (!oldprop)
+       if (!oldprop) {
+               if (strlen(name))
+                       return prom_add_property(np, newprop);
                return -ENODEV;
+       }
 
        rc = prom_update_property(np, newprop, oldprop);
        if (rc)
@@ -466,8 +472,12 @@ static int do_update_property(char *buf, size_t bufsize)
                else
                        action = PSERIES_DRCONF_MEM_REMOVE;
 
-               blocking_notifier_call_chain(&pSeries_reconfig_chain,
-                                            action, value);
+               rc = blocking_notifier_call_chain(&pSeries_reconfig_chain,
+                                                 action, value);
+               if (rc == NOTIFY_BAD) {
+                       rc = prom_update_property(np, oldprop, newprop);
+                       return -ENOMEM;
+               }
        }
 
        return 0;
@@ -529,10 +539,11 @@ out:
 }
 
 static const struct file_operations ofdt_fops = {
-       .write = ofdt_write
+       .write = ofdt_write,
+       .llseek = noop_llseek,
 };
 
-/* create /proc/ppc64/ofdt write-only by root */
+/* create /proc/powerpc/ofdt write-only by root */
 static int proc_ppc64_create_ofdt(void)
 {
        struct proc_dir_entry *ent;
@@ -540,7 +551,7 @@ static int proc_ppc64_create_ofdt(void)
        if (!machine_is(pseries))
                return 0;
 
-       ent = proc_create("ppc64/ofdt", S_IWUSR, NULL, &ofdt_fops);
+       ent = proc_create("powerpc/ofdt", S_IWUSR, NULL, &ofdt_fops);
        if (ent)
                ent->size = 0;