[media] v4l2-device: Register entity before calling subdev's registered ops
authorSakari Ailus <sakari.ailus@iki.fi>
Sun, 27 Dec 2015 23:45:00 +0000 (01:45 +0200)
committerMauro Carvalho Chehab <mchehab@osg.samsung.com>
Mon, 11 Jan 2016 14:19:16 +0000 (12:19 -0200)
Registering a V4L2 sub-device includes, among other things, registering
the related media entity and calling the sub-device's registered op. Since
patch "media: convert links from array to list", creating a link between
two pads requires registering the entity first. If the registered() op
involves link creation, the link list head will not be initialised before
it is used.

Resolve this by first registering the entity, then calling its
registered() op.

Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
drivers/media/v4l2-core/v4l2-device.c

index 85f724b53a148b422a3e4d9e5a37383756019eeb..2aa72aba4f172af958add1324089984b1c5966d0 100644 (file)
@@ -180,26 +180,26 @@ int v4l2_device_register_subdev(struct v4l2_device *v4l2_dev,
                return -ENODEV;
 
        sd->v4l2_dev = v4l2_dev;
-       if (sd->internal_ops && sd->internal_ops->registered) {
-               err = sd->internal_ops->registered(sd);
-               if (err)
-                       goto error_module;
-       }
-
        /* This just returns 0 if either of the two args is NULL */
        err = v4l2_ctrl_add_handler(v4l2_dev->ctrl_handler, sd->ctrl_handler, NULL);
        if (err)
-               goto error_unregister;
+               goto error_module;
 
 #if defined(CONFIG_MEDIA_CONTROLLER)
        /* Register the entity. */
        if (v4l2_dev->mdev) {
                err = media_device_register_entity(v4l2_dev->mdev, entity);
                if (err < 0)
-                       goto error_unregister;
+                       goto error_module;
        }
 #endif
 
+       if (sd->internal_ops && sd->internal_ops->registered) {
+               err = sd->internal_ops->registered(sd);
+               if (err)
+                       goto error_unregister;
+       }
+
        spin_lock(&v4l2_dev->lock);
        list_add_tail(&sd->list, &v4l2_dev->subdevs);
        spin_unlock(&v4l2_dev->lock);
@@ -207,8 +207,9 @@ int v4l2_device_register_subdev(struct v4l2_device *v4l2_dev,
        return 0;
 
 error_unregister:
-       if (sd->internal_ops && sd->internal_ops->unregistered)
-               sd->internal_ops->unregistered(sd);
+#if defined(CONFIG_MEDIA_CONTROLLER)
+       media_device_unregister_entity(entity);
+#endif
 error_module:
        if (!sd->owner_v4l2_dev)
                module_put(sd->owner);