Hi Kieran,

On Tue, May 23, 2017 at 06:40:08PM +0100, Kieran Bingham wrote:
> On 23/05/17 14:02, Sakari Ailus wrote:
> > Hi Kieran,
> > 
> > On Mon, May 22, 2017 at 06:36:38PM +0100, Kieran Bingham wrote:
> >> From: Kieran Bingham <[email protected]>
> >>
> >> Devices supporting multiple endpoints on a single device node must set
> >> their subdevice fwnode to the endpoint to allow distinct comparisons.
> >>
> >> Adapt the match_fwnode call to compare against the provided fwnodes
> >> first, but also to search for a comparison against the parent fwnode.
> >>
> >> This allows notifiers to pass the endpoint for comparison and still
> >> support existing subdevices which store their default parent device
> >> node.
> >>
> >> Signed-off-by: Kieran Bingham <[email protected]>
> >>
> >> ---
> >> v2:
> >>  - Added documentation comments
> >>  - simplified the OF match by adding match_fwnode_of()
> >>
> >> v3:
> >>  - Fix comments
> >>  - Fix sd_parent, and asd_parent usage
> >>
> >>  drivers/media/v4l2-core/v4l2-async.c | 36 ++++++++++++++++++++++++-----
> >>  1 file changed, 31 insertions(+), 5 deletions(-)
> >>
> >> diff --git a/drivers/media/v4l2-core/v4l2-async.c 
> >> b/drivers/media/v4l2-core/v4l2-async.c
> >> index cbd919d4edd2..12c0707851fd 100644
> >> --- a/drivers/media/v4l2-core/v4l2-async.c
> >> +++ b/drivers/media/v4l2-core/v4l2-async.c
> >> @@ -41,14 +41,40 @@ static bool match_devname(struct v4l2_subdev *sd,
> >>    return !strcmp(asd->match.device_name.name, dev_name(sd->dev));
> >>  }
> >>  
> >> +/*
> >> + * Check whether the two device_node pointers refer to the same OF node. 
> >> We
> >> + * can't compare pointers directly as they can differ if overlays have 
> >> been
> >> + * applied.
> >> + */
> >> +static bool match_fwnode_of(struct fwnode_handle *a, struct fwnode_handle 
> >> *b)
> >> +{
> >> +  return !of_node_cmp(of_node_full_name(to_of_node(a)),
> >> +                      of_node_full_name(to_of_node(b)));
> >> +}
> >> +
> >> +/*
> >> + * As a measure to support drivers which have not been converted to use
> >> + * endpoint matching, we also find the parent devices for cross-matching.
> >> + *
> >> + * When all devices use endpoint matching, this code can be simplified, 
> >> and the
> >> + * parent comparisons can be removed.
> >> + */
> >>  static bool match_fwnode(struct v4l2_subdev *sd, struct v4l2_async_subdev 
> >> *asd)
> >>  {
> >> -  if (!is_of_node(sd->fwnode) || !is_of_node(asd->match.fwnode.fwnode))
> >> -          return sd->fwnode == asd->match.fwnode.fwnode;
> >> +  struct fwnode_handle *asd_fwnode = asd->match.fwnode.fwnode;
> >> +  struct fwnode_handle *sd_parent, *asd_parent;
> >> +
> >> +  sd_parent = fwnode_graph_get_port_parent(sd->fwnode);
> >> +  asd_parent = fwnode_graph_get_port_parent(asd_fwnode);
> >> +
> >> +  if (!is_of_node(sd->fwnode) || !is_of_node(asd_fwnode))
> >> +          return sd->fwnode == asd_fwnode ||
> >> +                 sd_parent == asd_fwnode ||
> >> +                 sd->fwnode == asd_parent;
> >>  
> >> -  return !of_node_cmp(of_node_full_name(to_of_node(sd->fwnode)),
> >> -                      of_node_full_name(
> >> -                              to_of_node(asd->match.fwnode.fwnode)));
> >> +  return match_fwnode_of(sd->fwnode, asd_fwnode) ||
> >> +         match_fwnode_of(sd_parent, asd_fwnode) ||
> >> +         match_fwnode_of(sd->fwnode, asd_parent);
> >>  }
> >>  
> >>  static bool match_custom(struct v4l2_subdev *sd, struct v4l2_async_subdev 
> >> *asd)
> > 
> > Would this become easier to read if you handled all matching in what is
> > called match_fwnode_of() above, also for non-OF fwnodes? Essentially you'd
> > have what used to be match_fwnode() there, and new match_fwnode() would call
> > that function with all the three combinations.
> > 
> 
> 
> > I'd call the other function __match_fwnode() for instance.
> > 
> 
> 
> Yes - Took me a moment to understand what you meant here - but yes it's 
> leaner +
> cleaner:

Looks quite nice! Thanks! :)

> 
> 
> /*
>  * As a measure to support drivers which have not been converted to use
>  * endpoint matching, we also find the parent devices for cross-matching.
>  *
>  * When all devices use endpoint matching, this code can be simplified, and 
> the
>  * parent comparisons can be removed.
>  */
> 
> static bool __match_fwnode(struct fwnode_handle *a, struct fwnode_handle *b)
> {
>       if (is_of_node(a) || is_of_node(b))

I think you need && (not ||) although in practice I don't think it'd have
made any difference.

>               return !of_node_cmp(of_node_full_name(to_of_node(a)),
>                                   of_node_full_name(to_of_node(b)));
>       else
>               return a == b;
> }
> 
> static bool match_fwnode(struct v4l2_subdev *sd, struct v4l2_async_subdev 
> *asd)
> {
>       struct fwnode_handle *asd_fwnode = asd->match.fwnode.fwnode;
>       struct fwnode_handle *sd_parent, *asd_parent;
> 
>       sd_parent = fwnode_graph_get_port_parent(sd->fwnode);
>       asd_parent = fwnode_graph_get_port_parent(asd_fwnode);
> 
>       return __match_fwnode(sd->fwnode, asd_fwnode) ||
>              __match_fwnode(sd_parent, asd_fwnode) ||
>              __match_fwnode(sd->fwnode, asd_parent);
> }
> 

-- 
Kind regards,

Sakari Ailus
e-mail: [email protected]     XMPP: [email protected]

Reply via email to