Em Mon, 12 Oct 2015 23:12:41 +0300 Sakari Ailus sakari.ailus@iki.fi escreveu:
Hi Mauro,
On Mon, Oct 12, 2015 at 01:43:06PM -0300, Mauro Carvalho Chehab wrote:
From: Javier Martinez Canillas javier@osg.samsung.com
The omap3isp driver parses the graph endpoints to know how many subdevices needs to be registered async and register notifiers callbacks for to know when these are bound and when the async registrations are completed.
Currently the entities pad are linked with the correct ISP input interface when the subdevs are bound but it happens before entitities are registered with the media device so that won't work now that the entity links list is initialized on device registration.
So instead creating the pad links when the subdevice is bound, create them on the complete callback once all the subdevices have been bound but only try to create for the ones that have a bus configuration set during bound.
Change-Id: Ieeee2da9c812906435e70109aeff4fc748ca84b8 Signed-off-by: Javier Martinez Canillas javier@osg.samsung.com
drivers/media/platform/omap3isp/isp.c | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-)
diff --git a/drivers/media/platform/omap3isp/isp.c b/drivers/media/platform/omap3isp/isp.c index b8f6f81d2db2..69e7733d36cd 100644 --- a/drivers/media/platform/omap3isp/isp.c +++ b/drivers/media/platform/omap3isp/isp.c @@ -2321,26 +2321,33 @@ static int isp_subdev_notifier_bound(struct v4l2_async_notifier *async, struct v4l2_subdev *subdev, struct v4l2_async_subdev *asd) {
struct isp_device *isp = container_of(async, struct isp_device,
notifier);
struct isp_async_subdev *isd = container_of(asd, struct isp_async_subdev, asd);
int ret;
ret = isp_link_entity(isp, &subdev->entity, isd->bus.interface);
if (ret < 0)
return ret;
isd->sd = subdev; isd->sd->host_priv = &isd->bus;
return ret;
- return 0;
}
static int isp_subdev_notifier_complete(struct v4l2_async_notifier *async) { struct isp_device *isp = container_of(async, struct isp_device, notifier);
- struct v4l2_device *v4l2_dev = &isp->v4l2_dev;
- struct v4l2_subdev *sd;
- struct isp_bus_cfg *bus;
- int ret;
- list_for_each_entry(sd, &v4l2_dev->subdevs, list) {
list_for_each_entry(sd, &isp->v4l2_dev.subdevs, list) {
And you can drop local v4l2_dev.
This is Javier's patch, but I agree that this can be simplified.
/* Only try to link entities whose interface was set on bound */
if (sd->host_priv) {
bus = (struct isp_bus_cfg *)sd->host_priv;
struct isp_bus_cfg *bus = sd->host_priv;
And you can drop "bus" from the beginning of the function.
Perhaps not a big deal, but I think it's cleaner this way.
I actually prefer to allocate the local vars only once at the function :)
Ok, if the compiler optimizer is good enough, this won't make any difference, but, if the optimizer is not that good, at least on archs with not many registers like x86, allocating local vars inside loops may create extra code.
ret = isp_link_entity(isp, &sd->entity, bus->interface);
if (ret < 0)
return ret;
}
}
return v4l2_device_register_subdev_nodes(&isp->v4l2_dev);
}