mfd: AB3100 register access change to abx500 API
[safe/jmp/linux-2.6] / drivers / char / misc.c
index a5e0db9..cd650ca 100644 (file)
@@ -40,7 +40,6 @@
 #include <linux/miscdevice.h>
 #include <linux/kernel.h>
 #include <linux/major.h>
-#include <linux/slab.h>
 #include <linux/mutex.h>
 #include <linux/proc_fs.h>
 #include <linux/seq_file.h>
@@ -49,7 +48,7 @@
 #include <linux/device.h>
 #include <linux/tty.h>
 #include <linux/kmod.h>
-#include <linux/smp_lock.h>
+#include <linux/gfp.h>
 
 /*
  * Head entry for the doubly linked miscdevice list
@@ -61,9 +60,7 @@ static DEFINE_MUTEX(misc_mtx);
  * Assigned numbers, used for dynamic minors
  */
 #define DYNAMIC_MINORS 64 /* like dynamic majors */
-static unsigned char misc_minors[DYNAMIC_MINORS / 8];
-
-extern int pmu_device_init(void);
+static DECLARE_BITMAP(misc_minors, DYNAMIC_MINORS);
 
 #ifdef CONFIG_PROC_FS
 static void *misc_seq_start(struct seq_file *seq, loff_t *pos)
@@ -91,7 +88,7 @@ static int misc_seq_show(struct seq_file *seq, void *v)
 }
 
 
-static struct seq_operations misc_seq_ops = {
+static const struct seq_operations misc_seq_ops = {
        .start = misc_seq_start,
        .next  = misc_seq_next,
        .stop  = misc_seq_stop,
@@ -118,8 +115,7 @@ static int misc_open(struct inode * inode, struct file * file)
        struct miscdevice *c;
        int err = -ENODEV;
        const struct file_operations *old_fops, *new_fops = NULL;
-       
-       lock_kernel();
+
        mutex_lock(&misc_mtx);
        
        list_for_each_entry(c, &misc_list, list) {
@@ -148,6 +144,7 @@ static int misc_open(struct inode * inode, struct file * file)
        old_fops = file->f_op;
        file->f_op = new_fops;
        if (file->f_op->open) {
+               file->private_data = c;
                err=file->f_op->open(inode,file);
                if (err) {
                        fops_put(file->f_op);
@@ -157,7 +154,6 @@ static int misc_open(struct inode * inode, struct file * file)
        fops_put(old_fops);
 fail:
        mutex_unlock(&misc_mtx);
-       unlock_kernel();
        return err;
 }
 
@@ -168,7 +164,6 @@ static const struct file_operations misc_fops = {
        .open           = misc_open,
 };
 
-
 /**
  *     misc_register   -       register a miscellaneous device
  *     @misc: device structure
@@ -202,24 +197,23 @@ int misc_register(struct miscdevice * misc)
        }
 
        if (misc->minor == MISC_DYNAMIC_MINOR) {
-               int i = DYNAMIC_MINORS;
-               while (--i >= 0)
-                       if ( (misc_minors[i>>3] & (1 << (i&7))) == 0)
-                               break;
-               if (i<0) {
+               int i = find_first_zero_bit(misc_minors, DYNAMIC_MINORS);
+               if (i >= DYNAMIC_MINORS) {
                        mutex_unlock(&misc_mtx);
                        return -EBUSY;
                }
-               misc->minor = i;
+               misc->minor = DYNAMIC_MINORS - i - 1;
+               set_bit(i, misc_minors);
        }
 
-       if (misc->minor < DYNAMIC_MINORS)
-               misc_minors[misc->minor >> 3] |= 1 << (misc->minor & 7);
        dev = MKDEV(MISC_MAJOR, misc->minor);
 
-       misc->this_device = device_create(misc_class, misc->parent, dev, NULL,
-                                         "%s", misc->name);
+       misc->this_device = device_create(misc_class, misc->parent, dev,
+                                         misc, "%s", misc->name);
        if (IS_ERR(misc->this_device)) {
+               int i = DYNAMIC_MINORS - misc->minor - 1;
+               if (i < DYNAMIC_MINORS && i >= 0)
+                       clear_bit(i, misc_minors);
                err = PTR_ERR(misc->this_device);
                goto out;
        }
@@ -246,7 +240,7 @@ int misc_register(struct miscdevice * misc)
 
 int misc_deregister(struct miscdevice *misc)
 {
-       int i = misc->minor;
+       int i = DYNAMIC_MINORS - misc->minor - 1;
 
        if (list_empty(&misc->list))
                return -EINVAL;
@@ -254,9 +248,8 @@ int misc_deregister(struct miscdevice *misc)
        mutex_lock(&misc_mtx);
        list_del(&misc->list);
        device_destroy(misc_class, MKDEV(MISC_MAJOR, misc->minor));
-       if (i < DYNAMIC_MINORS && i>0) {
-               misc_minors[i>>3] &= ~(1 << (misc->minor & 7));
-       }
+       if (i < DYNAMIC_MINORS && i >= 0)
+               clear_bit(i, misc_minors);
        mutex_unlock(&misc_mtx);
        return 0;
 }
@@ -264,6 +257,17 @@ int misc_deregister(struct miscdevice *misc)
 EXPORT_SYMBOL(misc_register);
 EXPORT_SYMBOL(misc_deregister);
 
+static char *misc_devnode(struct device *dev, mode_t *mode)
+{
+       struct miscdevice *c = dev_get_drvdata(dev);
+
+       if (mode && c->mode)
+               *mode = c->mode;
+       if (c->nodename)
+               return kstrdup(c->nodename, GFP_KERNEL);
+       return NULL;
+}
+
 static int __init misc_init(void)
 {
        int err;
@@ -279,6 +283,7 @@ static int __init misc_init(void)
        err = -EIO;
        if (register_chrdev(MISC_MAJOR,"misc",&misc_fops))
                goto fail_printk;
+       misc_class->devnode = misc_devnode;
        return 0;
 
 fail_printk: