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/uio/uio.c | |
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/uio/uio.c')
-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; |