On Thu, 1 Nov 2012, Laurent Pinchart wrote:

> Hi,
> 
> On Monday 22 October 2012 15:36:03 Hans Verkuil wrote:
> > On Mon October 22 2012 14:50:14 Guennadi Liakhovetski wrote:
> > > On Mon, 22 Oct 2012, Hans Verkuil wrote:
> > > > On Mon October 22 2012 13:08:12 Guennadi Liakhovetski wrote:

[snip]

> > > > > The issue is simple: subdevice drivers have to recognise, when it's
> > > > > still too early to probe and return -EPROBE_DEFER. If you have a
> > > > > sensor, whose master clock is supplied from an external oscillator.
> > > > > You load its driver, it will happily get a clock reference and find no
> > > > > reason to fail probe(). It will initialise its subdevice and return
> > > > > from probing. Then, when your bridge driver probes, it will have no
> > > > > way to find that subdevice.
> 
> This is where I fundamentally disagree. You're right that the subdev driver 
> would have no reason to fail probe(). So why would it ? If the subdev driver 
> can succeed probe(), it should. -EPROBE_DEFER should only be returned if one 
> of the resources required by the subdev isn't available, such as a GPIO, 
> clock 
> or regulator for instance. When all resources required to make the subdev 
> usable are present, probe() should simply succeed.
> 
> This implies that you can pass the subdev platform data directly to the 
> subdev, either through the platform data pointer or through DT. Passing 
> subdev 
> platform data through the host/bridge is a hack. Removing it should, in my 
> opinion, be one of the goals of this patch.
> 
> This will leave us with the problem of locating the subdev from the host in 
> the notification callback. I had envision a different approach than yours to 
> fix the problem: similarly to your v4l2-clk service, I propose to make subdev 
> drivers registering themselves to the V4L2 core.

It's interesting to see, how we come back to where we started;-) In early 
soc-camera versions both hosts (bridge drivers) and clients (subdevices) 
used to register with the soc-camera core, which then did the matching... 
As we all know, this has been then dropped in favour of our present 
synchronous subdevice instantiation... oh, well:-)

> Instead of using I2C and 
> platform bus notifiers you would then have a single internal notifier 
> (possibly based on a subdev bus notifier if that makes sense) that would 
> support both hot-plug notification (notify drivers when a new subdev is 
> registered with the core) and cold-plug notification (go through the 
> registered subdevs list when a new async group (or whatever replaces the 
> async 
> groups if we get rid of multiple groups) is registered.

So, do I understand it right, that you're proposing something like the 
following:

=================
file bridge_drv.c
=================
static int __devinit bridge_probe(struct platform_device *pdev)
{
        ...
        v4l2_device_register(&pdev->dev, v4l2_dev);
        v4l2_clk_register();
        v4l2_async_register_notifier(v4l2_dev, notifier_desc);
        ...
}

=================
file subdev_drv.c
=================
static int __devinit subdev_probe(struct i2c_client *client,
                                const struct i2c_device_id *did)
{
        ...
        priv->clk = v4l2_clk_get();
        if (IS_ERR(priv->clk))
                return -EPROBE_DEFER;
        v4l2_i2c_subdev_init(subdev, client, &subdev_ops);
        v4l2_async_register_subdev(subdev);
}

=================
file v4l2_async.c
=================
static void v4l2_async_test_notify(v4l2_dev, subdev, notifier_desc)
{
        if (v4l2_async_belongs(subdev, notifier_desc)) {
                notifier_desc->subdev_notify(v4l2_dev, subdev, notifier_desc);
                if (v4l2_async_group_complete(notifier_desc, subdev))
                        notifier_desc->group_notify(v4l2_dev, group, 
notifier_desc);
        }
}

int v4l2_async_register_notifier(v4l2_dev, notifier_desc)
{
        notifier_desc->v4l2_dev = v4l2_dev;
        v4l2_async_for_each_subdev(subdev)
                v4l2_async_test_notify(v4l2_dev, subdev, notifier_desc);
}

int v4l2_async_register_subdev(subdev)
{
        v4l2_async_for_each_notifier(notifier_desc)
                v4l2_async_test_notify(notifier_desc->v4l2_dev, subdev, 
notifier_desc);
}

> > > > This problem is specific to platform subdev drivers, right? Since for
> > > > i2c subdevs you can use i2c_get_clientdata().
> > > 
> > > But how do you get the client? With DT you can follow our "remote"
> > > phandle, and without DT?
> > 
> > You would need a i2c_find_client() function for that. I would like to see
> > some more opinions about this.
> > 
> > > > I wonder whether it isn't a better idea to have platform_data embed a
> > > > standard struct containing a v4l2_subdev pointer. Subdevs can use
> > > > container_of to get from the address of that struct to the full
> > > > platform_data, and you don't have that extra dereference (i.e. a
> > > > pointer to the new struct which has a pointer to the actual
> > > > platform_data). The impact of that change is much smaller for existing
> > > > subdevs.
> > > 
> > > This standard platform data object is allocated by the bridge driver, so,
> > > it will not know where it is embedded in the subdevice specific platform
> > > data.
> > 
> > It should. The platform_data is specific to the subdev, so whoever is
> > allocating the platform_data has to know the size and contents of the
> > struct. Normally this structure is part of the board code for embedded
> > systems.
> > 
> > That soc-camera doesn't do this is a major soc-camera design flaw.
> > Soc-camera should not force the platform_data contents for subdev drivers.
> 
> That's something I tried to fix some time ago. Part of my cleanup patches 
> went 
> to mainline but I haven't had time to finish the implementation. Guennadi and 
> I were planning to work on this topic together at ELC-E, if time permits.
> 
> This being said, part of the information supplied through platform data, such 
> as lists of regulators, could be extracted to a standard V4L2 platform data 
> structure embedded in the driver-specific platform data. That could be useful 
> to provide helper functions, such as handling power on/off sequences.
> 
> > > > And if it isn't necessary for i2c subdev drivers, then I think we should
> > > > do this only for platform drivers.
> > > 
> > > See above, and I don't think we should implement 2 different methods.
> > > Besides, the change is very small. You anyway have to adapt sensor drivers
> > > to return -EPROBE_DEFER. This takes 2 lines of code:
> > > 
> > > + if (!client->dev.platform_data)
> > > +         return -EPROBE_DEFER;
> > > 
> > > If the driver isn't using platform data, that's it. If it is, you add two
> > > more lines:
> > > 
> > > - struct my_platform_data *pdata = client->dev.platform_data;
> > > + struct v4l2_subdev_platform_data *sdpd = client->dev.platform_data;
> > > + struct my_platform_data *pdata = sdpd->platform_data;
> > > 
> > > That's it. Of course, you have to do this everywhere, where the driver
> > > dereferences client->dev.platform_data, but even that shouldn't be too
> > > difficult.
> > 
> > I'd like to see other people's opinions on this as well. I do think I prefer
> > embedding it (in most if not all cases such a standard struct would be at
> > the beginning of the platform_data).
> 
> As explained above, embedding a standard V4L2 platform data structure (if we 
> decide to create one) in the driver-specific platform data has my preference 
> as well.
> 
> > > > That said, how does this new framework take care of timeouts if one of
> > > > the subdevs is never bound?
> > > 
> > > It doesn't.
> > > 
> > > > You don't want to have this wait indefinitely, I think.
> > > 
> > > There's no waiting:-) The bridge and other subdev drivers just remain
> > > loaded and inactive.
> > 
> > Is that what we want? I definitely would like to get other people's opinions
> > on this.
> > 
> > For the record: while it is waiting, can you safely rmmod the module?
> > Looking at the code I think you can, but I'm not 100% certain.
> 
> I'd like to propose a two layers approach. The lower layer would provide 
> direct notifications of subdev availability to host/bridge drivers. It could 
> be used directly, or an upper helper layer could handle the notifications and 
> provide a single complete callback when all requested subdevs are available.

Not sure you need 2 layers for this. You can just decide which callbacks 
to provide - per-subdev or per-group / global.

> Implementing a timeout-based instead of completetion callback-based upper 
> layer shouldn't be difficult, but I'm not sure whether it's a good approach. 
> I 
> think the host/bridge driver should complete its probe(), registering all the 
> resources it provides (such as clocks that can be used by sensors), even if 
> not all connected subdevs are available. The device nodes would only be 
> created later when all required subdevs are available (depending on the 
> driver 
> some device nodes could be created right-away, to allow mem-to-mem operation 
> for instance).

Thanks
Guennadi
---
Guennadi Liakhovetski, Ph.D.
Freelance Open-Source Software Developer
http://www.open-technology.de/
--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to