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 --- Hi Mauro,
You might want to add this patch before "media: Don't accept early-created links". Drivers that create links in their registered() callback will otherwise break.
I'm not extremely happy with the solution, and we might need to think how the life cycle of the graph objects and the initialisation of drivers work in detail. This would seem to fix the issue for now at least.
Regards, Sakari
drivers/media/v4l2-core/v4l2-device.c | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-)
diff --git a/drivers/media/v4l2-core/v4l2-device.c b/drivers/media/v4l2-core/v4l2-device.c index bb58d90..66a28af 100644 --- a/drivers/media/v4l2-core/v4l2-device.c +++ b/drivers/media/v4l2-core/v4l2-device.c @@ -171,26 +171,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); @@ -198,8 +198,7 @@ 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); + media_device_unregister_entity(entity); error_module: if (!sd->owner_v4l2_dev) module_put(sd->owner);