diff options
Diffstat (limited to 'drivers/uio')
-rw-r--r-- | drivers/uio/uio.c | 43 |
1 files changed, 37 insertions, 6 deletions
diff --git a/drivers/uio/uio.c b/drivers/uio/uio.c index 0fd2cda74244..3d4d65b0626f 100644 --- a/drivers/uio/uio.c +++ b/drivers/uio/uio.c | |||
@@ -23,9 +23,10 @@ | |||
23 | #include <linux/sched.h> | 23 | #include <linux/sched.h> |
24 | #include <linux/string.h> | 24 | #include <linux/string.h> |
25 | #include <linux/kobject.h> | 25 | #include <linux/kobject.h> |
26 | #include <linux/cdev.h> | ||
26 | #include <linux/uio_driver.h> | 27 | #include <linux/uio_driver.h> |
27 | 28 | ||
28 | #define UIO_MAX_DEVICES 255 | 29 | #define UIO_MAX_DEVICES (1U << MINORBITS) |
29 | 30 | ||
30 | struct uio_device { | 31 | struct uio_device { |
31 | struct module *owner; | 32 | struct module *owner; |
@@ -41,6 +42,7 @@ struct uio_device { | |||
41 | }; | 42 | }; |
42 | 43 | ||
43 | static int uio_major; | 44 | static int uio_major; |
45 | static struct cdev *uio_cdev; | ||
44 | static DEFINE_IDR(uio_idr); | 46 | static DEFINE_IDR(uio_idr); |
45 | static const struct file_operations uio_fops; | 47 | static const struct file_operations uio_fops; |
46 | 48 | ||
@@ -731,15 +733,44 @@ static const struct file_operations uio_fops = { | |||
731 | 733 | ||
732 | static int uio_major_init(void) | 734 | static int uio_major_init(void) |
733 | { | 735 | { |
734 | uio_major = register_chrdev(0, "uio", &uio_fops); | 736 | static const char name[] = "uio"; |
735 | if (uio_major < 0) | 737 | struct cdev *cdev = NULL; |
736 | return uio_major; | 738 | dev_t uio_dev = 0; |
737 | return 0; | 739 | int result; |
740 | |||
741 | result = alloc_chrdev_region(&uio_dev, 0, UIO_MAX_DEVICES, name); | ||
742 | if (result) | ||
743 | goto out; | ||
744 | |||
745 | result = -ENOMEM; | ||
746 | cdev = cdev_alloc(); | ||
747 | if (!cdev) | ||
748 | goto out_unregister; | ||
749 | |||
750 | cdev->owner = THIS_MODULE; | ||
751 | cdev->ops = &uio_fops; | ||
752 | kobject_set_name(&cdev->kobj, "%s", name); | ||
753 | |||
754 | result = cdev_add(cdev, uio_dev, UIO_MAX_DEVICES); | ||
755 | if (result) | ||
756 | goto out_put; | ||
757 | |||
758 | uio_major = MAJOR(uio_dev); | ||
759 | uio_cdev = cdev; | ||
760 | result = 0; | ||
761 | out: | ||
762 | return result; | ||
763 | out_put: | ||
764 | kobject_put(&cdev->kobj); | ||
765 | out_unregister: | ||
766 | unregister_chrdev_region(uio_dev, UIO_MAX_DEVICES); | ||
767 | goto out; | ||
738 | } | 768 | } |
739 | 769 | ||
740 | static void uio_major_cleanup(void) | 770 | static void uio_major_cleanup(void) |
741 | { | 771 | { |
742 | unregister_chrdev(uio_major, "uio"); | 772 | unregister_chrdev_region(MKDEV(uio_major, 0), UIO_MAX_DEVICES); |
773 | cdev_del(uio_cdev); | ||
743 | } | 774 | } |
744 | 775 | ||
745 | static int init_uio_class(void) | 776 | static int init_uio_class(void) |