Messages in this thread Patch in this message | | | From | (Eric W. Biederman) | Date | Sun, 26 Sep 2010 15:46:56 -0700 | Subject | [PATCH 1/5] uio: Simplify the lifetime logic of struct uio_device. |
| |
Embed struct device into struct uio_device, and use the refcounting and the release method of struct device to control struct uio_device.
This allows device_create and device_destroy to be replaced with the more standard device_register and device_unregister, and allows the struct device reference count to act as a reference count on struct idev as well.
Signed-off-by: Eric W. Biederman <ebiederm@aristanetworks.com> --- drivers/uio/uio.c | 42 ++++++++++++++++++++++++++++-------------- 1 files changed, 28 insertions(+), 14 deletions(-)
diff --git a/drivers/uio/uio.c b/drivers/uio/uio.c index 6285afb..565559c 100644 --- a/drivers/uio/uio.c +++ b/drivers/uio/uio.c @@ -30,7 +30,7 @@ struct uio_device { struct module *owner; - struct device *dev; + struct device device; int minor; atomic_t event; struct fasync_struct *async_queue; @@ -279,7 +279,7 @@ static int uio_dev_add_attributes(struct uio_device *idev) if (!map_found) { map_found = 1; idev->map_dir = kobject_create_and_add("maps", - &idev->dev->kobj); + &idev->device.kobj); if (!idev->map_dir) goto err_map; } @@ -304,7 +304,7 @@ static int uio_dev_add_attributes(struct uio_device *idev) if (!portio_found) { portio_found = 1; idev->portio_dir = kobject_create_and_add("portio", - &idev->dev->kobj); + &idev->device.kobj); if (!idev->portio_dir) goto err_portio; } @@ -339,7 +339,7 @@ err_map: kobject_put(&map->kobj); } kobject_put(idev->map_dir); - dev_err(idev->dev, "error creating sysfs files (%d)\n", ret); + dev_err(&idev->device, "error creating sysfs files (%d)\n", ret); return ret; } @@ -789,6 +789,13 @@ static void release_uio_class(void) uio_major_cleanup(); } +static void uio_device_release(struct device *dev) +{ + struct uio_device *idev = dev_get_drvdata(dev); + + kfree(idev); +} + /** * uio_register_device - register a new userspace IO device * @owner: module that creates the new device @@ -824,14 +831,19 @@ int __uio_register_device(struct module *owner, if (ret) goto err_get_minor; - idev->dev = device_create(&uio_class, parent, - MKDEV(uio_major, idev->minor), idev, - "uio%d", idev->minor); - if (IS_ERR(idev->dev)) { - printk(KERN_ERR "UIO: device register failed\n"); - ret = PTR_ERR(idev->dev); + idev->device.devt = MKDEV(uio_major, idev->minor); + idev->device.class = &uio_class; + idev->device.parent = parent; + idev->device.release = uio_device_release; + dev_set_drvdata(&idev->device, idev); + + ret = kobject_set_name(&idev->device.kobj, "uio%d", idev->minor); + if (ret) + goto err_device_create; + + ret = device_register(&idev->device); + if (ret) goto err_device_create; - } ret = uio_dev_add_attributes(idev); if (ret) @@ -851,7 +863,10 @@ int __uio_register_device(struct module *owner, err_request_irq: uio_dev_del_attributes(idev); err_uio_dev_add_attributes: - device_destroy(&uio_class, MKDEV(uio_major, idev->minor)); + uio_free_minor(idev); + device_unregister(&idev->device); + return ret; + err_device_create: uio_free_minor(idev); err_get_minor: @@ -882,8 +897,7 @@ void uio_unregister_device(struct uio_info *info) uio_dev_del_attributes(idev); - device_destroy(&uio_class, MKDEV(uio_major, idev->minor)); - kfree(idev); + device_unregister(&idev->device); return; } -- 1.7.2.2
| |