summaryrefslogtreecommitdiffstats
path: root/drivers/media/video/v4l2-device.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/video/v4l2-device.c')
-rw-r--r--drivers/media/video/v4l2-device.c58
1 files changed, 38 insertions, 20 deletions
diff --git a/drivers/media/video/v4l2-device.c b/drivers/media/video/v4l2-device.c
index 8a4b74f3129..94aa485ade5 100644
--- a/drivers/media/video/v4l2-device.c
+++ b/drivers/media/video/v4l2-device.c
@@ -26,48 +26,66 @@
int v4l2_device_register(struct device *dev, struct v4l2_device *v4l2_dev)
{
- if (dev == NULL || v4l2_dev == NULL)
+ if (v4l2_dev == NULL)
return -EINVAL;
- /* Warn if we apparently re-register a device */
- WARN_ON(dev_get_drvdata(dev) != NULL);
+
INIT_LIST_HEAD(&v4l2_dev->subdevs);
spin_lock_init(&v4l2_dev->lock);
v4l2_dev->dev = dev;
- snprintf(v4l2_dev->name, sizeof(v4l2_dev->name), "%s %s",
+ if (dev == NULL) {
+ /* If dev == NULL, then name must be filled in by the caller */
+ WARN_ON(!v4l2_dev->name[0]);
+ return 0;
+ }
+
+ /* Set name to driver name + device name if it is empty. */
+ if (!v4l2_dev->name[0])
+ snprintf(v4l2_dev->name, sizeof(v4l2_dev->name), "%s %s",
dev->driver->name, dev_name(dev));
+ if (dev_get_drvdata(dev))
+ v4l2_warn(v4l2_dev, "Non-NULL drvdata on register\n");
dev_set_drvdata(dev, v4l2_dev);
return 0;
}
EXPORT_SYMBOL_GPL(v4l2_device_register);
+void v4l2_device_disconnect(struct v4l2_device *v4l2_dev)
+{
+ if (v4l2_dev->dev) {
+ dev_set_drvdata(v4l2_dev->dev, NULL);
+ v4l2_dev->dev = NULL;
+ }
+}
+EXPORT_SYMBOL_GPL(v4l2_device_disconnect);
+
void v4l2_device_unregister(struct v4l2_device *v4l2_dev)
{
struct v4l2_subdev *sd, *next;
- if (v4l2_dev == NULL || v4l2_dev->dev == NULL)
+ if (v4l2_dev == NULL)
return;
- dev_set_drvdata(v4l2_dev->dev, NULL);
- /* unregister subdevs */
+ v4l2_device_disconnect(v4l2_dev);
+
+ /* Unregister subdevs */
list_for_each_entry_safe(sd, next, &v4l2_dev->subdevs, list)
v4l2_device_unregister_subdev(sd);
-
- v4l2_dev->dev = NULL;
}
EXPORT_SYMBOL_GPL(v4l2_device_unregister);
-int v4l2_device_register_subdev(struct v4l2_device *dev, struct v4l2_subdev *sd)
+int v4l2_device_register_subdev(struct v4l2_device *v4l2_dev,
+ struct v4l2_subdev *sd)
{
/* Check for valid input */
- if (dev == NULL || sd == NULL || !sd->name[0])
+ if (v4l2_dev == NULL || sd == NULL || !sd->name[0])
return -EINVAL;
/* Warn if we apparently re-register a subdev */
- WARN_ON(sd->dev != NULL);
+ WARN_ON(sd->v4l2_dev != NULL);
if (!try_module_get(sd->owner))
return -ENODEV;
- sd->dev = dev;
- spin_lock(&dev->lock);
- list_add_tail(&sd->list, &dev->subdevs);
- spin_unlock(&dev->lock);
+ sd->v4l2_dev = v4l2_dev;
+ spin_lock(&v4l2_dev->lock);
+ list_add_tail(&sd->list, &v4l2_dev->subdevs);
+ spin_unlock(&v4l2_dev->lock);
return 0;
}
EXPORT_SYMBOL_GPL(v4l2_device_register_subdev);
@@ -75,12 +93,12 @@ EXPORT_SYMBOL_GPL(v4l2_device_register_subdev);
void v4l2_device_unregister_subdev(struct v4l2_subdev *sd)
{
/* return if it isn't registered */
- if (sd == NULL || sd->dev == NULL)
+ if (sd == NULL || sd->v4l2_dev == NULL)
return;
- spin_lock(&sd->dev->lock);
+ spin_lock(&sd->v4l2_dev->lock);
list_del(&sd->list);
- spin_unlock(&sd->dev->lock);
- sd->dev = NULL;
+ spin_unlock(&sd->v4l2_dev->lock);
+ sd->v4l2_dev = NULL;
module_put(sd->owner);
}
EXPORT_SYMBOL_GPL(v4l2_device_unregister_subdev);