diff options
| author | Eric W. Biederman <ebiederm@aristanetworks.com> | 2010-09-14 14:38:36 -0400 |
|---|---|---|
| committer | Greg Kroah-Hartman <gregkh@suse.de> | 2010-10-22 13:16:43 -0400 |
| commit | c66fdab64fd791bdd49fed4f5785643251ddf586 (patch) | |
| tree | 2d75b8ce0d1566f173511fc439b6f096bf30d9ca /drivers | |
| parent | 91960a46c658b719c03fba80f1c60a96393bbcfd (diff) | |
uio: Statically allocate uio_class and use class .dev_attrs.
Instead of adding uio class attributes manually after the uio device has
been created and we have sent a uevent to userspace, use the class
attribute mechanism. This removes races and makes the code simpler.
At the same time don't bother to dynamically allocate a struct class for
uio, just declare one statically. Less code is needed and it is easier
to set the class parameters.tune the class
Signed-off-by: Eric W. Biederman <ebiederm@aristanetworks.com>
Reviewed-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Hans J. Koch <hjk@linutronix.de>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers')
| -rw-r--r-- | drivers/uio/uio.c | 53 |
1 files changed, 18 insertions, 35 deletions
diff --git a/drivers/uio/uio.c b/drivers/uio/uio.c index 3d4d65b0626f..3fe9a9da42d1 100644 --- a/drivers/uio/uio.c +++ b/drivers/uio/uio.c | |||
| @@ -46,9 +46,6 @@ static struct cdev *uio_cdev; | |||
| 46 | static DEFINE_IDR(uio_idr); | 46 | static DEFINE_IDR(uio_idr); |
| 47 | static const struct file_operations uio_fops; | 47 | static const struct file_operations uio_fops; |
| 48 | 48 | ||
| 49 | /* UIO class infrastructure */ | ||
| 50 | static struct class *uio_class; | ||
| 51 | |||
| 52 | /* Protect idr accesses */ | 49 | /* Protect idr accesses */ |
| 53 | static DEFINE_MUTEX(minor_lock); | 50 | static DEFINE_MUTEX(minor_lock); |
| 54 | 51 | ||
| @@ -233,7 +230,6 @@ static ssize_t show_name(struct device *dev, | |||
| 233 | struct uio_device *idev = dev_get_drvdata(dev); | 230 | struct uio_device *idev = dev_get_drvdata(dev); |
| 234 | return sprintf(buf, "%s\n", idev->info->name); | 231 | return sprintf(buf, "%s\n", idev->info->name); |
| 235 | } | 232 | } |
| 236 | static DEVICE_ATTR(name, S_IRUGO, show_name, NULL); | ||
| 237 | 233 | ||
| 238 | static ssize_t show_version(struct device *dev, | 234 | static ssize_t show_version(struct device *dev, |
| 239 | struct device_attribute *attr, char *buf) | 235 | struct device_attribute *attr, char *buf) |
| @@ -241,7 +237,6 @@ static ssize_t show_version(struct device *dev, | |||
| 241 | struct uio_device *idev = dev_get_drvdata(dev); | 237 | struct uio_device *idev = dev_get_drvdata(dev); |
| 242 | return sprintf(buf, "%s\n", idev->info->version); | 238 | return sprintf(buf, "%s\n", idev->info->version); |
| 243 | } | 239 | } |
| 244 | static DEVICE_ATTR(version, S_IRUGO, show_version, NULL); | ||
| 245 | 240 | ||
| 246 | static ssize_t show_event(struct device *dev, | 241 | static ssize_t show_event(struct device *dev, |
| 247 | struct device_attribute *attr, char *buf) | 242 | struct device_attribute *attr, char *buf) |
| @@ -249,17 +244,18 @@ static ssize_t show_event(struct device *dev, | |||
| 249 | struct uio_device *idev = dev_get_drvdata(dev); | 244 | struct uio_device *idev = dev_get_drvdata(dev); |
| 250 | return sprintf(buf, "%u\n", (unsigned int)atomic_read(&idev->event)); | 245 | return sprintf(buf, "%u\n", (unsigned int)atomic_read(&idev->event)); |
| 251 | } | 246 | } |
| 252 | static DEVICE_ATTR(event, S_IRUGO, show_event, NULL); | ||
| 253 | 247 | ||
| 254 | static struct attribute *uio_attrs[] = { | 248 | static struct device_attribute uio_class_attributes[] = { |
| 255 | &dev_attr_name.attr, | 249 | __ATTR(name, S_IRUGO, show_name, NULL), |
| 256 | &dev_attr_version.attr, | 250 | __ATTR(version, S_IRUGO, show_version, NULL), |
| 257 | &dev_attr_event.attr, | 251 | __ATTR(event, S_IRUGO, show_event, NULL), |
| 258 | NULL, | 252 | {} |
| 259 | }; | 253 | }; |
| 260 | 254 | ||
| 261 | static struct attribute_group uio_attr_grp = { | 255 | /* UIO class infrastructure */ |
| 262 | .attrs = uio_attrs, | 256 | static struct class uio_class = { |
| 257 | .name = "uio", | ||
| 258 | .dev_attrs = uio_class_attributes, | ||
| 263 | }; | 259 | }; |
| 264 | 260 | ||
| 265 | /* | 261 | /* |
| @@ -276,10 +272,6 @@ static int uio_dev_add_attributes(struct uio_device *idev) | |||
| 276 | struct uio_port *port; | 272 | struct uio_port *port; |
| 277 | struct uio_portio *portio; | 273 | struct uio_portio *portio; |
| 278 | 274 | ||
| 279 | ret = sysfs_create_group(&idev->dev->kobj, &uio_attr_grp); | ||
| 280 | if (ret) | ||
| 281 | goto err_group; | ||
| 282 | |||
| 283 | for (mi = 0; mi < MAX_UIO_MAPS; mi++) { | 275 | for (mi = 0; mi < MAX_UIO_MAPS; mi++) { |
| 284 | mem = &idev->info->mem[mi]; | 276 | mem = &idev->info->mem[mi]; |
| 285 | if (mem->size == 0) | 277 | if (mem->size == 0) |
| @@ -347,8 +339,6 @@ err_map: | |||
| 347 | kobject_put(&map->kobj); | 339 | kobject_put(&map->kobj); |
| 348 | } | 340 | } |
| 349 | kobject_put(idev->map_dir); | 341 | kobject_put(idev->map_dir); |
| 350 | sysfs_remove_group(&idev->dev->kobj, &uio_attr_grp); | ||
| 351 | err_group: | ||
| 352 | dev_err(idev->dev, "error creating sysfs files (%d)\n", ret); | 342 | dev_err(idev->dev, "error creating sysfs files (%d)\n", ret); |
| 353 | return ret; | 343 | return ret; |
| 354 | } | 344 | } |
| @@ -374,8 +364,6 @@ static void uio_dev_del_attributes(struct uio_device *idev) | |||
| 374 | kobject_put(&port->portio->kobj); | 364 | kobject_put(&port->portio->kobj); |
| 375 | } | 365 | } |
| 376 | kobject_put(idev->portio_dir); | 366 | kobject_put(idev->portio_dir); |
| 377 | |||
| 378 | sysfs_remove_group(&idev->dev->kobj, &uio_attr_grp); | ||
| 379 | } | 367 | } |
| 380 | 368 | ||
| 381 | static int uio_get_minor(struct uio_device *idev) | 369 | static int uio_get_minor(struct uio_device *idev) |
| @@ -775,7 +763,6 @@ static void uio_major_cleanup(void) | |||
| 775 | 763 | ||
| 776 | static int init_uio_class(void) | 764 | static int init_uio_class(void) |
| 777 | { | 765 | { |
| 778 | struct class *class; | ||
| 779 | int ret; | 766 | int ret; |
| 780 | 767 | ||
| 781 | /* This is the first time in here, set everything up properly */ | 768 | /* This is the first time in here, set everything up properly */ |
| @@ -783,16 +770,14 @@ static int init_uio_class(void) | |||
| 783 | if (ret) | 770 | if (ret) |
| 784 | goto exit; | 771 | goto exit; |
| 785 | 772 | ||
| 786 | class = class_create(THIS_MODULE, "uio"); | 773 | ret = class_register(&uio_class); |
| 787 | if (IS_ERR(class)) { | 774 | if (ret) { |
| 788 | ret = IS_ERR(class); | 775 | printk(KERN_ERR "class_register failed for uio\n"); |
| 789 | printk(KERN_ERR "class_create failed for uio\n"); | 776 | goto err_class_register; |
| 790 | goto err_class_create; | ||
| 791 | } | 777 | } |
| 792 | uio_class = class; | ||
| 793 | return 0; | 778 | return 0; |
| 794 | 779 | ||
| 795 | err_class_create: | 780 | err_class_register: |
| 796 | uio_major_cleanup(); | 781 | uio_major_cleanup(); |
| 797 | exit: | 782 | exit: |
| 798 | return ret; | 783 | return ret; |
| @@ -800,9 +785,7 @@ exit: | |||
| 800 | 785 | ||
| 801 | static void release_uio_class(void) | 786 | static void release_uio_class(void) |
| 802 | { | 787 | { |
| 803 | /* Ok, we cheat as we know we only have one uio_class */ | 788 | class_unregister(&uio_class); |
| 804 | class_destroy(uio_class); | ||
| 805 | uio_class = NULL; | ||
| 806 | uio_major_cleanup(); | 789 | uio_major_cleanup(); |
| 807 | } | 790 | } |
| 808 | 791 | ||
| @@ -841,7 +824,7 @@ int __uio_register_device(struct module *owner, | |||
| 841 | if (ret) | 824 | if (ret) |
| 842 | goto err_get_minor; | 825 | goto err_get_minor; |
| 843 | 826 | ||
| 844 | idev->dev = device_create(uio_class, parent, | 827 | idev->dev = device_create(&uio_class, parent, |
| 845 | MKDEV(uio_major, idev->minor), idev, | 828 | MKDEV(uio_major, idev->minor), idev, |
| 846 | "uio%d", idev->minor); | 829 | "uio%d", idev->minor); |
| 847 | if (IS_ERR(idev->dev)) { | 830 | if (IS_ERR(idev->dev)) { |
| @@ -868,7 +851,7 @@ int __uio_register_device(struct module *owner, | |||
| 868 | err_request_irq: | 851 | err_request_irq: |
| 869 | uio_dev_del_attributes(idev); | 852 | uio_dev_del_attributes(idev); |
| 870 | err_uio_dev_add_attributes: | 853 | err_uio_dev_add_attributes: |
| 871 | device_destroy(uio_class, MKDEV(uio_major, idev->minor)); | 854 | device_destroy(&uio_class, MKDEV(uio_major, idev->minor)); |
| 872 | err_device_create: | 855 | err_device_create: |
| 873 | uio_free_minor(idev); | 856 | uio_free_minor(idev); |
| 874 | err_get_minor: | 857 | err_get_minor: |
| @@ -899,7 +882,7 @@ void uio_unregister_device(struct uio_info *info) | |||
| 899 | 882 | ||
| 900 | uio_dev_del_attributes(idev); | 883 | uio_dev_del_attributes(idev); |
| 901 | 884 | ||
| 902 | device_destroy(uio_class, MKDEV(uio_major, idev->minor)); | 885 | device_destroy(&uio_class, MKDEV(uio_major, idev->minor)); |
| 903 | kfree(idev); | 886 | kfree(idev); |
| 904 | 887 | ||
| 905 | return; | 888 | return; |
