Pull percpu-dtc into release branch
[pandora-kernel.git] / arch / mips / kernel / vpe.c
index 4596249..c9ee9d2 100644 (file)
@@ -29,6 +29,7 @@
  */
 
 #include <linux/kernel.h>
+#include <linux/device.h>
 #include <linux/module.h>
 #include <linux/fs.h>
 #include <linux/init.h>
@@ -48,6 +49,7 @@
 #include <asm/cacheflush.h>
 #include <asm/atomic.h>
 #include <asm/cpu.h>
+#include <asm/mips_mt.h>
 #include <asm/processor.h>
 #include <asm/system.h>
 #include <asm/vpe.h>
@@ -64,6 +66,7 @@ typedef void *vpe_handle;
 
 static char module_name[] = "vpe";
 static int major;
+static const int minor = 1;    /* fixed for now  */
 
 #ifdef CONFIG_MIPS_APSP_KSPD
  static struct kspd_notifications kspd_events;
@@ -1076,6 +1079,7 @@ static int getcwd(char *buff, int size)
 static int vpe_open(struct inode *inode, struct file *filp)
 {
        int minor, ret;
+       enum vpe_state state;
        struct vpe *v;
        struct vpe_notifications *not;
 
@@ -1090,7 +1094,8 @@ static int vpe_open(struct inode *inode, struct file *filp)
                return -ENODEV;
        }
 
-       if (v->state != VPE_STATE_UNUSED) {
+       state = xchg(&v->state, VPE_STATE_INUSE);
+       if (state != VPE_STATE_UNUSED) {
                dvpe();
 
                printk(KERN_DEBUG "VPE loader: tc in use dumping regs\n");
@@ -1105,9 +1110,6 @@ static int vpe_open(struct inode *inode, struct file *filp)
                cleanup_tc(get_tc(minor));
        }
 
-       // allocate it so when we get write ops we know it's expected.
-       v->state = VPE_STATE_INUSE;
-
        /* this of-course trashes what was there before... */
        v->pbuffer = vmalloc(P_SIZE);
        v->plen = P_SIZE;
@@ -1205,7 +1207,7 @@ static ssize_t vpe_write(struct file *file, const char __user * buffer,
        return ret;
 }
 
-static struct file_operations vpe_fops = {
+static const struct file_operations vpe_fops = {
        .owner = THIS_MODULE,
        .open = vpe_open,
        .release = vpe_release,
@@ -1365,12 +1367,15 @@ static void kspd_sp_exit( int sp_id)
 }
 #endif
 
+static struct device *vpe_dev;
+
 static int __init vpe_module_init(void)
 {
        struct vpe *v = NULL;
+       struct device *dev;
        struct tc *t;
        unsigned long val;
-       int i;
+       int i, err;
 
        if (!cpu_has_mipsmt) {
                printk("VPE loader: not a MIPS MT capable processor\n");
@@ -1383,6 +1388,14 @@ static int __init vpe_module_init(void)
                return major;
        }
 
+       dev = device_create(mt_class, NULL, MKDEV(major, minor),
+                           "tc%d", minor);
+       if (IS_ERR(dev)) {
+               err = PTR_ERR(dev);
+               goto out_chrdev;
+       }
+       vpe_dev = dev;
+
        dmt();
        dvpe();
 
@@ -1478,6 +1491,11 @@ static int __init vpe_module_init(void)
        kspd_events.kspd_sp_exit = kspd_sp_exit;
 #endif
        return 0;
+
+out_chrdev:
+       unregister_chrdev(major, module_name);
+
+       return err;
 }
 
 static void __exit vpe_module_exit(void)
@@ -1490,6 +1508,7 @@ static void __exit vpe_module_exit(void)
                }
        }
 
+       device_destroy(mt_class, MKDEV(major, minor));
        unregister_chrdev(major, module_name);
 }