@@ -717,19 +717,26 @@ int __must_check __media_device_register(struct media_device *mdev,
/* Set version 0 to indicate user-space that the graph is static */
mdev->topology_version = 0;
+ media_devnode_init(&mdev->devnode);
+
ret = media_devnode_register(&mdev->devnode, owner);
if (ret < 0)
- return ret;
+ goto err_put;
ret = device_create_file(&mdev->devnode.dev, &dev_attr_model);
- if (ret < 0) {
- media_devnode_unregister(&mdev->devnode);
- return ret;
- }
+ if (ret < 0)
+ goto err_unregister;
dev_dbg(mdev->dev, "Media device registered\n");
return 0;
+
+err_unregister:
+ media_devnode_unregister(&mdev->devnode);
+err_put:
+ put_device(&mdev->devnode.dev);
+
+ return ret;
}
EXPORT_SYMBOL_GPL(__media_device_register);
@@ -803,6 +810,7 @@ void media_device_unregister(struct media_device *mdev)
device_remove_file(&mdev->devnode.dev, &dev_attr_model);
dev_dbg(mdev->dev, "Media device unregistering\n");
media_devnode_unregister(&mdev->devnode);
+ put_device(&mdev->devnode.dev);
}
EXPORT_SYMBOL_GPL(media_device_unregister);
@@ -197,6 +197,11 @@ static const struct file_operations media_devnode_fops = {
.llseek = no_llseek,
};
+void media_devnode_init(struct media_devnode *devnode)
+{
+ device_initialize(&devnode->dev);
+}
+
int __must_check media_devnode_register(struct media_devnode *devnode,
struct module *owner)
{
@@ -228,7 +233,6 @@ int __must_check media_devnode_register(struct media_devnode *devnode,
if (devnode->parent)
devnode->dev.parent = devnode->parent;
dev_set_name(&devnode->dev, "media%d", devnode->minor);
- device_initialize(&devnode->dev);
/* Part 3: Add the media and character devices */
ret = cdev_device_add(&devnode->cdev, &devnode->dev);
@@ -246,7 +250,6 @@ int __must_check media_devnode_register(struct media_devnode *devnode,
mutex_lock(&media_devnode_lock);
clear_bit(devnode->minor, media_devnode_nums);
mutex_unlock(&media_devnode_lock);
- put_device(&devnode->dev);
return ret;
}
@@ -261,8 +264,7 @@ void media_devnode_unregister(struct media_devnode *devnode)
clear_bit(MEDIA_FLAG_REGISTERED, &devnode->flags);
mutex_unlock(&media_devnode_lock);
- cdev_del(&devnode->cdev);
- device_unregister(&devnode->dev);
+ cdev_device_del(&devnode->cdev, &devnode->dev);
mutex_lock(&media_devnode_lock);
clear_bit(devnode->minor, media_devnode_nums);
@@ -272,7 +274,7 @@ void media_devnode_unregister(struct media_devnode *devnode)
/*
* Initialise media for linux
*/
-static int __init media_devnode_init(void)
+static int __init media_devnode_module_init(void)
{
int ret;
@@ -294,14 +296,14 @@ static int __init media_devnode_init(void)
return 0;
}
-static void __exit media_devnode_exit(void)
+static void __exit media_devnode_module_exit(void)
{
bus_unregister(&media_bus_type);
unregister_chrdev_region(media_dev_t, MEDIA_NUM_DEVICES);
}
-subsys_initcall(media_devnode_init);
-module_exit(media_devnode_exit)
+subsys_initcall(media_devnode_module_init);
+module_exit(media_devnode_module_exit)
MODULE_AUTHOR("Laurent Pinchart <laurent.pinchart@ideasonboard.com>");
MODULE_DESCRIPTION("Device node registration for media drivers");
@@ -89,6 +89,17 @@ struct media_devnode {
/* dev to media_devnode */
#define to_media_devnode(cd) container_of(cd, struct media_devnode, dev)
+/**
+ * media_devnode_init - initialise a media devnode
+ *
+ * @devnode: struct media_devnode we want to initialise
+ *
+ * Initialise a media devnode. Note that after initialising the media
+ * devnode is refcounted. Releasing references to it may be done using
+ * put_device().
+ */
+void media_devnode_init(struct media_devnode *devnode);
+
/**
* media_devnode_register - register a media device node
*
@@ -99,11 +110,9 @@ struct media_devnode {
* with the kernel. An error is returned if no free minor number can be found,
* or if the registration of the device node fails.
*
- * Zero is returned on success.
- *
- * Note that if the media_devnode_register call fails, the release() callback of
- * the media_devnode structure is *not* called, so the caller is responsible for
- * freeing any data.
+ * Zero is returned on success. Note that in case
+ * media_devnode_register() fails, the caller is responsible for
+ * releasing the reference to the device using put_device().
*/
int __must_check media_devnode_register(struct media_devnode *devnode,
struct module *owner);