diff options
| -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) |
