Re: [PATCH] media: v4l2-async: Put fwnode after last access

2020-12-28 Thread Laurent Pinchart
Hi Ezequiel,

Thank you for the patch.

On Mon, Dec 28, 2020 at 09:17:25AM -0300, Ezequiel Garcia wrote:
> fwnode_handle_put() should be called after the fwnode
> is last accessed. Fix it.
> 
> Fixes: b98158d837ef ("media: v4l2-async: Accept endpoints and devices for 
> fwnode matching")
> Signed-off-by: Ezequiel Garcia 
> ---
>  drivers/media/v4l2-core/v4l2-async.c | 6 --
>  1 file changed, 4 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/media/v4l2-core/v4l2-async.c 
> b/drivers/media/v4l2-core/v4l2-async.c
> index e3ab003a6c85..1303c9b83138 100644
> --- a/drivers/media/v4l2-core/v4l2-async.c
> +++ b/drivers/media/v4l2-core/v4l2-async.c
> @@ -78,6 +78,7 @@ static bool match_fwnode(struct v4l2_async_notifier 
> *notifier,
>   bool asd_fwnode_is_ep;
>   bool sd_fwnode_is_ep;
>   struct device *dev;
> + bool match;
>  
>   /*
>* Both the subdev and the async subdev can provide either an endpoint
> @@ -113,9 +114,10 @@ static bool match_fwnode(struct v4l2_async_notifier 
> *notifier,
>   other_fwnode = sd->fwnode;
>   }
>  
> - fwnode_handle_put(dev_fwnode);
> + match = (dev_fwnode == other_fwnode);
>  
> - if (dev_fwnode != other_fwnode)

This only performs a pointer comparison, it doesn't access dev_fwnode. I
don't think the change is necessary.

> + fwnode_handle_put(dev_fwnode);
> + if (!match)
>   return false;
>  
>   /*

-- 
Regards,

Laurent Pinchart


Re: [PATCH v7 08/12] media: uvcvideo: Use dev_ printk aliases

2020-12-24 Thread Laurent Pinchart
Hi Andy,

On Thu, Dec 24, 2020 at 02:59:34PM +0200, Andy Shevchenko wrote:
> On Wed, Dec 23, 2020 at 3:39 PM Ricardo Ribalda wrote:
> >
> > Replace all the uses of printk() and uvc_printk() with its
> > equivalent dev_ alias macros.
> 
> > Modify uvc_warn_once() macro to use dev_info instead printk().
> 
> ...
> 
> > +#define uvc_warn_once(_dev, warn, fmt, ...)\
> > +do {   \
> > +   if (!test_and_set_bit(warn, &(_dev)->warnings)) \
> > +   dev_info(&(_dev)->udev->dev, fmt, ##__VA_ARGS__);   \
> > +} while (0)
> 
> ...
> 
> Why not to use dev_warn_once() instead?

uvc_warn_once() prints the warning once per device, not once globally.

-- 
Regards,

Laurent Pinchart


Re: [PATCH v3 13/14] include: media: v4l2-fwnode: Include v4l2_fwnode_bus_type

2020-12-24 Thread Laurent Pinchart
Hi Daniel,

Thank you for the patch.

On Thu, Dec 24, 2020 at 01:09:06AM +, Daniel Scally wrote:
> V4L2 fwnode bus types are enumerated in v4l2-fwnode.c, meaning they aren't
> available to the rest of the kernel. Move the enum to the corresponding
> header so that I can use the label to refer to those values.
> 
> Suggested-by: Andy Shevchenko 
> Signed-off-by: Daniel Scally 
> ---
> Changes in v3
>   - Patch introduced
> 
>  drivers/media/v4l2-core/v4l2-fwnode.c | 11 ---
>  include/media/v4l2-fwnode.h   | 22 ++
>  2 files changed, 22 insertions(+), 11 deletions(-)
> 
> diff --git a/drivers/media/v4l2-core/v4l2-fwnode.c 
> b/drivers/media/v4l2-core/v4l2-fwnode.c
> index 5353e37eb950..c1c2b3060532 100644
> --- a/drivers/media/v4l2-core/v4l2-fwnode.c
> +++ b/drivers/media/v4l2-core/v4l2-fwnode.c
> @@ -28,17 +28,6 @@
>  #include 
>  #include 
>  
> -enum v4l2_fwnode_bus_type {
> - V4L2_FWNODE_BUS_TYPE_GUESS = 0,
> - V4L2_FWNODE_BUS_TYPE_CSI2_CPHY,
> - V4L2_FWNODE_BUS_TYPE_CSI1,
> - V4L2_FWNODE_BUS_TYPE_CCP2,
> - V4L2_FWNODE_BUS_TYPE_CSI2_DPHY,
> - V4L2_FWNODE_BUS_TYPE_PARALLEL,
> - V4L2_FWNODE_BUS_TYPE_BT656,
> - NR_OF_V4L2_FWNODE_BUS_TYPE,
> -};
> -
>  static const struct v4l2_fwnode_bus_conv {
>   enum v4l2_fwnode_bus_type fwnode_bus_type;
>   enum v4l2_mbus_type mbus_type;
> diff --git a/include/media/v4l2-fwnode.h b/include/media/v4l2-fwnode.h
> index 4365430eea6f..d306a28bda96 100644
> --- a/include/media/v4l2-fwnode.h
> +++ b/include/media/v4l2-fwnode.h
> @@ -213,6 +213,28 @@ struct v4l2_fwnode_connector {
>   } connector;
>  };
>  
> +/**
> + * enum v4l2_fwnode_bus_type - Video bus types defined by firmware properties
> + * @V4L2_FWNODE_BUS_TYPE_GUESS: Default value if no bus-type fwnode property
> + * @V4L2_FWNODE_BUS_TYPE_CSI2_CPHY: MIPI CSI-2 bus, C-PHY physical layer
> + * @V4L2_FWNODE_BUS_TYPE_CSI1: MIPI CSI-1 bus
> + * @V4L2_FWNODE_BUS_TYPE_CCP2: SMIA Compact Camera Port 2 bus
> + * @V4L2_FWNODE_BUS_TYPE_CSI2_DPHY: MIPI CSI-2 bus, D-PHY physical layer
> + * @V4L2_FWNODE_BUS_TYPE_PARALLEL: Camera Parallel Interface bus
> + * @V4L2_FWNODE_BUS_TYPE_BT656: BT656 video format bus-type

s/BT656 video/BT.656 video/

Reviewed-by: Laurent Pinchart 

> + * @NR_OF_V4L2_FWNODE_BUS_TYPE: Number of bus-types
> + */
> +enum v4l2_fwnode_bus_type {
> + V4L2_FWNODE_BUS_TYPE_GUESS = 0,
> + V4L2_FWNODE_BUS_TYPE_CSI2_CPHY,
> + V4L2_FWNODE_BUS_TYPE_CSI1,
> + V4L2_FWNODE_BUS_TYPE_CCP2,
> + V4L2_FWNODE_BUS_TYPE_CSI2_DPHY,
> + V4L2_FWNODE_BUS_TYPE_PARALLEL,
> + V4L2_FWNODE_BUS_TYPE_BT656,
> +     NR_OF_V4L2_FWNODE_BUS_TYPE,
> +};
> +
>  /**
>   * v4l2_fwnode_endpoint_parse() - parse all fwnode node properties
>   * @fwnode: pointer to the endpoint's fwnode handle

-- 
Regards,

Laurent Pinchart


Re: [PATCH v3 07/14] software_node: Add support for fwnode_graph*() family of functions

2020-12-24 Thread Laurent Pinchart
  return endpoint;
> > +}
> > +
> > +static struct fwnode_handle *
> > +software_node_graph_get_remote_endpoint(const struct fwnode_handle *fwnode)
> > +{
> > +   struct swnode *swnode = to_swnode(fwnode);
> > +   const struct software_node_ref_args *ref;
> > +   const struct property_entry *prop;
> > +
> > +   if (!swnode)
> > +   return NULL;
> > +
> > +   prop = property_entry_get(swnode->node->properties, 
> > "remote-endpoint");
> > +   if (!prop || prop->type != DEV_PROP_REF || prop->is_inline)
> > +   return NULL;
> > +
> > +   ref = prop->pointer;
> > +
> > +   return software_node_get(software_node_fwnode(ref[0].node));
> > +}
> > +
> > +static struct fwnode_handle *
> > +software_node_graph_get_port_parent(struct fwnode_handle *fwnode)
> > +{
> > +   struct swnode *swnode = to_swnode(fwnode);
> > +
> > +   swnode = swnode->parent;
> > +   if (swnode && !strcmp(swnode->node->name, "ports"))
> > +   swnode = swnode->parent;
> > +
> > +   return swnode ? software_node_get(>fwnode) : NULL;
> > +}
> > +
> > +static int
> > +software_node_graph_parse_endpoint(const struct fwnode_handle *fwnode,
> > +  struct fwnode_endpoint *endpoint)
> > +{
> > +   struct swnode *swnode = to_swnode(fwnode);
> > +   int ret;
> > +
> > +   /* Ports have naming style "port@n", we need to select the n */
> 
> > +   ret = kstrtou32(swnode->parent->node->name + 
> > FWNODE_GRAPH_PORT_NAME_PREFIX_LEN,
> 
> Maybe a temporary variable?
> 
>   unsigned int prefix_len = FWNODE_GRAPH_PORT_NAME_PREFIX_LEN;
>   ...
>   ret = kstrtou32(swnode->parent->node->name + prefix_len,

Honestly I'm wondering if those macros don't hinder readability. I'd
rather write

+ strlen("port@")

and let the compiler optimize this to a compile-time constant.

> > +   10, >port);
> > +   if (ret)
> > +   return ret;
> > +
> > +   endpoint->id = swnode->id;
> > +   endpoint->local_fwnode = fwnode;
> > +
> > +   return 0;
> > +}
> > +
> >  static const struct fwnode_operations software_node_ops = {
> > .get = software_node_get,
> > .put = software_node_put,
> > @@ -551,7 +657,11 @@ static const struct fwnode_operations 
> > software_node_ops = {
> > .get_parent = software_node_get_parent,
> > .get_next_child_node = software_node_get_next_child,
> > .get_named_child_node = software_node_get_named_child_node,
> > -   .get_reference_args = software_node_get_reference_args
> > +   .get_reference_args = software_node_get_reference_args,
> > +   .graph_get_next_endpoint = software_node_graph_get_next_endpoint,
> > +   .graph_get_remote_endpoint = 
> > software_node_graph_get_remote_endpoint,
> > +   .graph_get_port_parent = software_node_graph_get_port_parent,
> > +   .graph_parse_endpoint = software_node_graph_parse_endpoint,
> >  };
> >
> >  /* 
> > -- 
> > */

-- 
Regards,

Laurent Pinchart


Re: [PATCH v3 07/14] software_node: Add support for fwnode_graph*() family of functions

2020-12-24 Thread Laurent Pinchart
 software_node_get(software_node_fwnode(ref[0].node));
> +}
> +
> +static struct fwnode_handle *
> +software_node_graph_get_port_parent(struct fwnode_handle *fwnode)
> +{
> + struct swnode *swnode = to_swnode(fwnode);
> +
> + swnode = swnode->parent;
> + if (swnode && !strcmp(swnode->node->name, "ports"))
> + swnode = swnode->parent;
> +
> + return swnode ? software_node_get(>fwnode) : NULL;
> +}
> +
> +static int
> +software_node_graph_parse_endpoint(const struct fwnode_handle *fwnode,
> +struct fwnode_endpoint *endpoint)
> +{
> + struct swnode *swnode = to_swnode(fwnode);
> + int ret;
> +
> + /* Ports have naming style "port@n", we need to select the n */
> + ret = kstrtou32(swnode->parent->node->name + 
> FWNODE_GRAPH_PORT_NAME_PREFIX_LEN,
> + 10, >port);

Same here.

I wonder if we should add a check to ensure parent->node->name is long
enough (and possibly even start with the right prefix), as otherwise the
pointer passed to kstrtou32() may be past the end of the string. Maybe
this is overkill, if we can rely on the fact that software nodes have
correct names.

Reviewed-by: Laurent Pinchart 

> + if (ret)
> + return ret;
> +
> + endpoint->id = swnode->id;
> + endpoint->local_fwnode = fwnode;
> +
> + return 0;
> +}
> +
>  static const struct fwnode_operations software_node_ops = {
>   .get = software_node_get,
>   .put = software_node_put,
> @@ -551,7 +657,11 @@ static const struct fwnode_operations software_node_ops 
> = {
>   .get_parent = software_node_get_parent,
>   .get_next_child_node = software_node_get_next_child,
>   .get_named_child_node = software_node_get_named_child_node,
> - .get_reference_args = software_node_get_reference_args
> + .get_reference_args = software_node_get_reference_args,
> + .graph_get_next_endpoint = software_node_graph_get_next_endpoint,
> + .graph_get_remote_endpoint = software_node_graph_get_remote_endpoint,
> + .graph_get_port_parent = software_node_graph_get_port_parent,
> + .graph_parse_endpoint = software_node_graph_parse_endpoint,
>  };
>  
>  /* 
> -- */

-- 
Regards,

Laurent Pinchart


Re: [PATCH v3 06/14] include: fwnode.h: Define format macros for ports and endpoints

2020-12-24 Thread Laurent Pinchart
Hi Daniel,

Thank you for the patch.

On Thu, Dec 24, 2020 at 02:17:07PM +0200, Andy Shevchenko wrote:
> On Thu, Dec 24, 2020 at 3:12 AM Daniel Scally wrote:
> >
> > OF, ACPI and software_nodes all implement graphs including nodes for ports
> > and endpoints. These are all intended to be named with a common schema,
> > as "port@n" and "endpoint@n" where n is an unsigned int representing the
> > index of the node. To ensure commonality across the subsystems, provide a
> > set of macros to define the format.
> 
> Nitpicks below, but in general that's what I meant, thanks!
> 
> Reviewed-by: Andy Shevchenko 
> (after addressing nitpicks)
> 
> > Suggested-by: Andy Shevchenko 
> > Signed-off-by: Daniel Scally 
> > ---
> > Changes in v3
> > - Patch introduced
> >
> >  include/linux/fwnode.h | 13 +
> >  1 file changed, 13 insertions(+)
> >
> > diff --git a/include/linux/fwnode.h b/include/linux/fwnode.h
> > index 9506f8ec0974..52889efceb7d 100644
> > --- a/include/linux/fwnode.h
> > +++ b/include/linux/fwnode.h
> > @@ -32,6 +32,19 @@ struct fwnode_endpoint {
> > const struct fwnode_handle *local_fwnode;
> >  };
> >
> > +/*
> > + * ports and endpoints defined in OF, ACPI and as software_nodes should all
> > + * follow a common naming scheme; use these macros to ensure commonality 
> > across
> > + * the subsystems.
> > + *
> > + * The *PREFIX_LEN macros refer to the length of the "port@" and 
> > "endpoint@"
> 
> *PREFIX_LEN -> *_PREFIX_LEN
> 
> > + * sections of the naming scheme.
> > + */
> > +#define FWNODE_GRAPH_PORT_NAME_FORMAT  "port@%u"
> > +#define FWNODE_GRAPH_PORT_NAME_PREFIX_LEN  5
> > +#define FWNODE_GRAPH_ENDPOINT_NAME_FORMAT  "endpoint@%u"
> > +#define FWNODE_GRAPH_ENDPOINT_PREFIX_LEN   9
> 
> _FORMAT -> _FMT (however, V4L2 guys may correct me, because IIRC _FMT
> suffix is also used for other things in v4l2.

This isn't related to V4L2, so it doesn't matter much :-) I personally
prefer spelling names out in full when that wouldn't result in too long
lines, but it's really a matter of personal preference, I don't mind
either way.

Reviewed-by: Laurent Pinchart 

> >  #define NR_FWNODE_REFERENCE_ARGS   8
> >
> >  /**

-- 
Regards,

Laurent Pinchart


Re: [PATCH] dt-bindings: Drop redundant maxItems/items

2020-12-23 Thread Laurent Pinchart
On Wed, Dec 23, 2020 at 10:54:26AM -0700, Rob Herring wrote:
> On Mon, Dec 21, 2020 at 11:39 PM Sam Ravnborg  wrote:
> >
> > Hi Rob,
> >
> > On Mon, Dec 21, 2020 at 09:06:45PM -0700, Rob Herring wrote:
> > > 'maxItems' equal to the 'items' list length is redundant. 'maxItems' is
> > > preferred for a single entry while greater than 1 should have an 'items'
> > > list.
> > >
> > > A meta-schema check for this is pending once these existing cases are
> > > fixed.
> > >
> > > Cc: Laurent Pinchart 
> > > Cc: Vinod Koul 
> > > Cc: Mark Brown 
> > > Cc: Greg Kroah-Hartman 
> > > Cc: Jassi Brar 
> > > Cc: dri-de...@lists.freedesktop.org
> > > Cc: dmaeng...@vger.kernel.org
> > > Cc: alsa-de...@alsa-project.org
> > > Cc: linux-...@vger.kernel.org
> > > Signed-off-by: Rob Herring 
> >
> > With one comment below,
> > Acked-by: Sam Ravnborg 
> >
> > > ---
> > > diff --git a/Documentation/devicetree/bindings/usb/renesas,usbhs.yaml 
> > > b/Documentation/devicetree/bindings/usb/renesas,usbhs.yaml
> > > index 737c1f47b7de..54c361d4a7af 100644
> > > --- a/Documentation/devicetree/bindings/usb/renesas,usbhs.yaml
> > > +++ b/Documentation/devicetree/bindings/usb/renesas,usbhs.yaml
> > > @@ -74,11 +74,8 @@ properties:
> > >
> > >phys:
> > >  maxItems: 1
> > > -items:
> > > -  - description: phandle + phy specifier pair.
> >
> > The description may help some people, so keeping the
> > description and deleting maxItems would maybe be better.
> 
> Do we really want to describe 'phys' hundreds of times? No. The
> question I ask on the descriptions is could it be generated instead.

I agree. If the description had mentioned why particular PHY was
referenced, I would have kept that, but "the phy is a phy" is probably
not something we want to duplicate everywhere.

-- 
Regards,

Laurent Pinchart


Re: [PATCH v6 06/11] media: uvcvideo: Implement UVC_EXT_GPIO_UNIT

2020-12-23 Thread Laurent Pinchart
t privacy GPIO IRQ %d. Continuing 
> without privacy events\n",
> +  ret);
> +
>   uvc_trace(UVC_TRACE_PROBE, "UVC device initialized.\n");
>   usb_enable_autosuspend(udev);
>   return 0;
> diff --git a/drivers/media/usb/uvc/uvc_entity.c 
> b/drivers/media/usb/uvc/uvc_entity.c
> index ca3a9c2eec27..6a9ba5b498db 100644
> --- a/drivers/media/usb/uvc/uvc_entity.c
> +++ b/drivers/media/usb/uvc/uvc_entity.c
> @@ -105,6 +105,7 @@ static int uvc_mc_init_entity(struct uvc_video_chain 
> *chain,
>   case UVC_OTT_DISPLAY:
>   case UVC_OTT_MEDIA_TRANSPORT_OUTPUT:
>   case UVC_EXTERNAL_VENDOR_SPECIFIC:
> + case UVC_EXT_GPIO_UNIT:
>   default:
>   function = MEDIA_ENT_F_V4L2_SUBDEV_UNKNOWN;
>   break;
> diff --git a/drivers/media/usb/uvc/uvcvideo.h 
> b/drivers/media/usb/uvc/uvcvideo.h
> index 64a3d901db19..132513a66ee5 100644
> --- a/drivers/media/usb/uvc/uvcvideo.h
> +++ b/drivers/media/usb/uvc/uvcvideo.h
> @@ -6,6 +6,7 @@
>  #error "The uvcvideo.h header is deprecated, use linux/uvcvideo.h instead."
>  #endif /* __KERNEL__ */
>  
> +#include 
>  #include 
>  #include 
>  #include 
> @@ -37,6 +38,8 @@
>   (UVC_ENTITY_IS_TERM(entity) && \
>   ((entity)->type & 0x8000) == UVC_TERM_OUTPUT)
>  
> +#define UVC_EXT_GPIO_UNIT0x7ffe
> +#define UVC_EXT_GPIO_UNIT_ID 0x100
>  
>  /* 
>   * GUIDs
> @@ -56,6 +59,9 @@
>  #define UVC_GUID_UVC_SELECTOR \
>   {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
>0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02}
> +#define UVC_GUID_EXT_GPIO_CONTROLLER \
> + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
> +  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x03}
>  
>  #define UVC_GUID_FORMAT_MJPEG \
>   { 'M',  'J',  'P',  'G', 0x00, 0x00, 0x10, 0x00, \
> @@ -213,6 +219,7 @@
>   */
>  
>  struct uvc_device;
> +struct gpio_desc;

Alphabetical order ? :-)

Otherwise this looks good, pending an agreement on how to handle the
case where the GPIO can't generate an IRQ.

>  
>  /* TODO: Put the most frequently accessed fields at the beginning of
>   * structures to maximize cache efficiency.
> @@ -353,6 +360,14 @@ struct uvc_entity {
>   u8  *bmControls;
>   u8  *bmControlsType;
>   } extension;
> +
> + struct {
> + u8  bControlSize;
> + u8  *bmControls;
> + struct gpio_desc *gpio_privacy;
> + int irq;
> + atomic_t gpio_privacy_value;
> + } gpio;
>   };
>  
>   u8 bNrInPins;
> @@ -690,6 +705,8 @@ struct uvc_device {
>   struct uvc_control *ctrl;
>   const void *data;
>   } async_ctrl;
> +
> + struct uvc_entity *gpio_unit;
>  };
>  
>  enum uvc_handle_state {

-- 
Regards,

Laurent Pinchart


Re: [PATCH v6 04/11] media: uvcvideo: Add uvc_ctrl_status_event_direct

2020-12-23 Thread Laurent Pinchart
Hi Ricardo,

Thank you for the patch.

On Wed, Dec 23, 2020 at 12:04:39AM +0100, Ricardo Ribalda wrote:
> Provide a code path for events that can be sent without a work-queue,
> this is, that do not belong to an URB and are not handled in the top
> half on an irq-handled.
> 
> Signed-off-by: Ricardo Ribalda 
> ---
>  drivers/media/usb/uvc/uvc_ctrl.c | 35 +++-
>  drivers/media/usb/uvc/uvcvideo.h |  2 ++
>  2 files changed, 32 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/media/usb/uvc/uvc_ctrl.c 
> b/drivers/media/usb/uvc/uvc_ctrl.c
> index 9f6174a10e73..5fe228a3213b 100644
> --- a/drivers/media/usb/uvc/uvc_ctrl.c
> +++ b/drivers/media/usb/uvc/uvc_ctrl.c
> @@ -1254,17 +1254,14 @@ static void uvc_ctrl_send_slave_event(struct 
> uvc_video_chain *chain,
>   uvc_ctrl_send_event(chain, handle, ctrl, mapping, val, changes);
>  }
>  
> -static void uvc_ctrl_status_event_work(struct work_struct *work)
> +static void __uvc_ctrl_status_event(struct uvc_device *dev,
> + struct uvc_ctrl_work *w)

As this function doesn't deal with the work queue, should it receive the
members of uvc_ctrl_work as direct arguments ? You could then drop the
separate uvc_ctrl_status_event_direct(), or rather rename this function
to uvc_ctrl_status_event_direct().

Speaking of names, maybe uvc_ctrl_status_event() should be renamed to
uvc_ctrl_status_event_async(), and this function become
uvc_ctrl_status_event() ?

>  {
> - struct uvc_device *dev = container_of(work, struct uvc_device,
> -   async_ctrl.work);
> - struct uvc_ctrl_work *w = >async_ctrl;
>   struct uvc_video_chain *chain = w->chain;
>   struct uvc_control_mapping *mapping;
>   struct uvc_control *ctrl = w->ctrl;
>   struct uvc_fh *handle;
>   unsigned int i;
> - int ret;
>  
>   mutex_lock(>ctrl_mutex);
>  
> @@ -1291,6 +1288,16 @@ static void uvc_ctrl_status_event_work(struct 
> work_struct *work)
>   }
>  
>   mutex_unlock(>ctrl_mutex);
> +}
> +
> +static void uvc_ctrl_status_event_work(struct work_struct *work)
> +{
> + struct uvc_device *dev = container_of(work, struct uvc_device,
> +   async_ctrl.work);
> + struct uvc_ctrl_work *w = >async_ctrl;
> + int ret;
> +
> + __uvc_ctrl_status_event(dev, w);
>  
>   /* Resubmit the URB. */
>   w->urb->interval = dev->int_ep->desc.bInterval;
> @@ -1321,6 +1328,24 @@ bool uvc_ctrl_status_event(struct urb *urb, struct 
> uvc_video_chain *chain,
>   return true;
>  }
>  
> +void uvc_ctrl_status_event_direct(struct uvc_video_chain *chain,
> +   struct uvc_control *ctrl, const u8 *data)
> +{
> + struct uvc_device *dev = chain->dev;
> + struct uvc_ctrl_work w;
> +
> + if (list_empty(>info.mappings)) {
> + ctrl->handle = NULL;
> + return;
> + }
> +
> + w.data = data;
> + w.chain = chain;
> + w.ctrl = ctrl;
> +
> + __uvc_ctrl_status_event(dev, );
> +}
> +
>  static bool uvc_ctrl_xctrls_has_control(const struct v4l2_ext_control 
> *xctrls,
>   unsigned int xctrls_count, u32 id)
>  {
> diff --git a/drivers/media/usb/uvc/uvcvideo.h 
> b/drivers/media/usb/uvc/uvcvideo.h
> index c50b0546901f..d7954dcc2b60 100644
> --- a/drivers/media/usb/uvc/uvcvideo.h
> +++ b/drivers/media/usb/uvc/uvcvideo.h
> @@ -845,6 +845,8 @@ void uvc_ctrl_cleanup_device(struct uvc_device *dev);
>  int uvc_ctrl_restore_values(struct uvc_device *dev);
>  bool uvc_ctrl_status_event(struct urb *urb, struct uvc_video_chain *chain,
>  struct uvc_control *ctrl, const u8 *data);
> +void uvc_ctrl_status_event_direct(struct uvc_video_chain *chain,
> +   struct uvc_control *ctrl, const u8 *data);
>  
>  int uvc_ctrl_begin(struct uvc_video_chain *chain);
>  int __uvc_ctrl_commit(struct uvc_fh *handle, int rollback,

-- 
Regards,

Laurent Pinchart


Re: [PATCH v5 09/12] media: uvcvideo: Implement UVC_QUIRK_PRIVACY_DURING_STREAM

2020-12-23 Thread Laurent Pinchart
Hi Ricardo,

On Tue, Dec 22, 2020 at 09:04:19PM +0100, Ricardo Ribalda wrote:
> On Tue, Dec 22, 2020 at 11:30 AM Laurent Pinchart wrote:
> > On Mon, Dec 21, 2020 at 05:48:16PM +0100, Ricardo Ribalda wrote:
> > > Some devices, can only read the privacy_pin if the device is
> >
> > s/devices,/devices/
> >
> > > streaming.
> > >
> > > This patch implement a quirk for such devices, in order to avoid invalid
> > > reads and/or spurious events.
> > >
> > > Signed-off-by: Ricardo Ribalda 
> > > ---
> > >  drivers/media/usb/uvc/uvc_driver.c | 57 --
> > >  drivers/media/usb/uvc/uvc_queue.c  |  3 ++
> > >  drivers/media/usb/uvc/uvcvideo.h   |  4 +++
> > >  3 files changed, 61 insertions(+), 3 deletions(-)
> > >
> > > diff --git a/drivers/media/usb/uvc/uvc_driver.c 
> > > b/drivers/media/usb/uvc/uvc_driver.c
> > > index 72516101fdd0..7af37d4bd60a 100644
> > > --- a/drivers/media/usb/uvc/uvc_driver.c
> > > +++ b/drivers/media/usb/uvc/uvc_driver.c
> > > @@ -7,6 +7,7 @@
> > >   */
> > >
> > >  #include 
> > > +#include 
> > >  #include 
> > >  #include 
> > >  #include 
> > > @@ -1472,6 +1473,17 @@ static int uvc_parse_control(struct uvc_device 
> > > *dev)
> > >  /* 
> > > -
> > >   * Privacy GPIO
> > >   */
> >
> > There should be a blank line here.
> >
> > > +static bool uvc_gpio_is_streaming(struct uvc_device *dev)
> > > +{
> > > + struct uvc_streaming *streaming;
> > > +
> > > + list_for_each_entry(streaming, >streams, list) {
> > > + if (uvc_queue_streaming(>queue))
> > > + return true;
> > > + }
> > > +
> > > + return false;
> > > +}
> > >
> > >
> >
> > But not too blank lines here.
> >
> > >  static u8 uvc_gpio_update_value(struct uvc_device *dev,
> > > @@ -1499,7 +1511,12 @@ static int uvc_gpio_get_cur(struct uvc_device 
> > > *dev, struct uvc_entity *entity,
> > >   if (cs != UVC_CT_PRIVACY_CONTROL || size < 1)
> > >   return -EINVAL;
> > >
> > > + if ((dev->quirks & UVC_QUIRK_PRIVACY_DURING_STREAM) &&
> > > + !uvc_gpio_is_streaming(dev))
> > > + return -EBUSY;
> > > +
> > >   *(uint8_t *)data = uvc_gpio_update_value(dev, entity);
> > > +
> > >   return 0;
> > >  }
> > >
> > > @@ -1528,19 +1545,50 @@ static struct uvc_entity 
> > > *uvc_gpio_find_entity(struct uvc_device *dev)
> > >   return NULL;
> > >  }
> > >
> > > -static irqreturn_t uvc_gpio_irq(int irq, void *data)
> > > +void uvc_privacy_gpio_event(struct uvc_device *dev)
> > >  {
> > > - struct uvc_device *dev = data;
> > >   struct uvc_entity *unit;
> > >
> > > +
> > >   unit = uvc_gpio_find_entity(dev);
> > >   if (!unit)
> > > - return IRQ_HANDLED;
> > > + return;
> > >
> > >   uvc_gpio_update_value(dev, unit);
> > > +}
> > > +
> > > +static irqreturn_t uvc_gpio_irq(int irq, void *data)
> > > +{
> > > + struct uvc_device *dev = data;
> > > +
> > > + /* Ignore privacy events during streamoff */
> > > + if (dev->quirks & UVC_QUIRK_PRIVACY_DURING_STREAM)
> > > + if (!uvc_gpio_is_streaming(dev))
> > > + return IRQ_HANDLED;
> >
> > I'm still a bit concerned of race conditions. When stopping the stream,
> > vb2_queue.streaming is set to 0 after calling the driver's .stop_stream()
> > handler. This means that the device will cut power before
> > uvc_gpio_is_streaming() can detect that streaming has stopped, and the
> > GPIO could thus trigger an IRQ.
> 
> On the affected devices I have not seen this. I guess it takes some
> time to discharge. Anyway I am implementing a workaround. Tell me if
> it is too ugly.
> 
> > You mentioned that devices have a pull-up or pull-down on the GPIO line.
> > As there are only two devices affected, do you know if it's a pull-up or
> > pull-down ? Would it be worse to expose that state to userspace than to
> > return -EBUSY when reading the control ?
> 
> The module has a 100K pull up. 

Re: [PATCH v5 07/12] media: uvcvideo: Implement UVC_EXT_GPIO_UNIT

2020-12-22 Thread Laurent Pinchart
Hi Ricardo,

On Tue, Dec 22, 2020 at 07:36:52PM +0100, Ricardo Ribalda wrote:
> On Tue, Dec 22, 2020 at 9:34 AM Laurent Pinchart wrote:
> > On Mon, Dec 21, 2020 at 05:48:14PM +0100, Ricardo Ribalda wrote:
> > > Some devices can implement a physical switch to disable the input of the
> > > camera on demand. Think of it like an elegant privacy sticker.
> > >
> > > The system can read the status of the privacy switch via a GPIO.
> > >
> > > It is important to know the status of the switch, e.g. to notify the
> > > user when the camera will produce black frames and a videochat
> > > application is used.
> > >
> > > In some systems, the GPIO is connected to main SoC instead of the
> > > camera controller, with the connected reported by the system firmware
> >
> > s/connected/connection/
> >
> > > (ACPI or DT). In that case, the UVC device isn't aware of the GPIO. We
> > > need to implement a virtual entity to handle the GPIO fully on the
> > > driver side.
> > >
> > > For example, for ACPI-based systems, the GPIO is reported in the USB
> > > device object:
> > >
> > >   Scope (\_SB.PCI0.XHCI.RHUB.HS07)
> > >   {
> > >
> > > /.../
> > >
> > > Name (_CRS, ResourceTemplate ()  // _CRS: Current Resource Settings
> > > {
> > > GpioIo (Exclusive, PullDefault, 0x, 0x, 
> > > IoRestrictionOutputOnly,
> > > "\\_SB.PCI0.GPIO", 0x00, ResourceConsumer, ,
> > > )
> > > {   // Pin list
> > > 0x0064
> > > }
> > > })
> > > Name (_DSD, Package (0x02)  // _DSD: Device-Specific Data
> > > {
> > > ToUUID ("daffd814-6eba-4d8c-8a91-bc9bbf4aa301") /* Device 
> > > Properties for _DSD */,
> > > Package (0x01)
> > > {
> > > Package (0x02)
> > > {
> > > "privacy-gpio",
> > > Package (0x04)
> > > {
> > > \_SB.PCI0.XHCI.RHUB.HS07,
> > > Zero,
> > > Zero,
> > > One
> > > }
> > > }
> > > }
> > > })
> > >   }
> > >
> > > Signed-off-by: Ricardo Ribalda 
> > > ---
> > >  drivers/media/usb/uvc/uvc_ctrl.c   |   7 ++
> > >  drivers/media/usb/uvc/uvc_driver.c | 156 +
> > >  drivers/media/usb/uvc/uvc_entity.c |   1 +
> > >  drivers/media/usb/uvc/uvcvideo.h   |  16 +++
> > >  4 files changed, 180 insertions(+)
> > >
> > > diff --git a/drivers/media/usb/uvc/uvc_ctrl.c 
> > > b/drivers/media/usb/uvc/uvc_ctrl.c
> > > index 528254230535..a430fa666897 100644
> > > --- a/drivers/media/usb/uvc/uvc_ctrl.c
> > > +++ b/drivers/media/usb/uvc/uvc_ctrl.c
> > > @@ -1300,6 +1300,10 @@ static void __uvc_ctrl_status_event_work(struct 
> > > uvc_device *dev,
> > >
> > >   mutex_unlock(>ctrl_mutex);
> > >
> > > + /* Events not started by the UVC device. E.g. the GPIO unit */
> > > + if (!w->urb)
> > > + return;
> > > +
> > >   /* Resubmit the URB. */
> > >   w->urb->interval = dev->int_ep->desc.bInterval;
> > >   ret = usb_submit_urb(w->urb, GFP_KERNEL);
> > > @@ -2317,6 +2321,9 @@ int uvc_ctrl_init_device(struct uvc_device *dev)
> > >   } else if (UVC_ENTITY_TYPE(entity) == UVC_ITT_CAMERA) {
> > >   bmControls = entity->camera.bmControls;
> > >   bControlSize = entity->camera.bControlSize;
> > > + } else if (UVC_ENTITY_TYPE(entity) == UVC_EXT_GPIO_UNIT) {
> > > + bmControls = entity->gpio.bmControls;
> > > + bControlSize = entity->gpio.bControlSize;
> > >   }
> > >
> > >   /* Remove bogus/blacklisted controls */
> > > diff --git a/drivers/media/usb/uvc/uvc_driver.c 
> > > b/drivers/media/usb/uvc/uvc_driver.c
> > > index c0c5f75ade40..72516101fdd0 100644
> > > --- a/drivers/media/usb/uvc/uvc_driver.c
> > > +++ b/drivers/media/usb/uvc/uvc_driver.c
> > > @@ -7,6 +7,7 @@
> > >   */
> > >
> > >  #inc

Re: [PATCH v6] drm/bridge: add it6505 driver

2020-12-22 Thread Laurent Pinchart
Hi Allen,

On Tue, Dec 22, 2020 at 11:29:34AM +, allen.c...@ite.com.tw wrote:
> Hi
> 
> It has been about two weeks since I posted v6 and haven't heard anything.
> Consider this a gentle ping.
> 
> Just wondering if the set needs additional work and I will fix and
> upstream again.

I'm afraid I don't have enough bandwidth these days to review all new
bridge drivers :-S Maybe one of the DRM bridge maintainers would have
more time to spend ?

> -Original Message-
> From: Allen Chen (陳柏宇) 
> Sent: Tuesday, December 08, 2020 6:58 PM
> Cc: Jau-Chih Tseng (曾昭智); Hermes Wu (吳佳宏); Kenneth Hung (洪家倫); Allen Chen 
> (陳柏宇); Pi-Hsun Shih; Jitao Shi; Yilun Lin; Hermes Wu (吳佳宏); Andrzej Hajda; 
> Neil Armstrong; Laurent Pinchart; Jonas Karlman; Jernej Skrabec; David 
> Airlie; Daniel Vetter; Matthias Brugger; open list; open list:DRM DRIVERS; 
> moderated list:ARM/Mediatek SoC support; moderated list:ARM/Mediatek SoC 
> support
> Subject: [PATCH v6] drm/bridge: add it6505 driver
> 
> This adds support for the iTE IT6505.
> This device can convert DPI signal to DP output.
> 
> From: Allen Chen 
> Signed-off-by: Jitao Shi 
> Signed-off-by: Pi-Hsun Shih 
> Signed-off-by: Yilun Lin 
> Signed-off-by: Hermes Wu 
> Signed-off-by: Allen Chen 
> ---
>  drivers/gpu/drm/bridge/Kconfig  |7 +
>  drivers/gpu/drm/bridge/Makefile |1 +
>  drivers/gpu/drm/bridge/ite-it6505.c | 3343 +++
>  3 files changed, 3351 insertions(+)
>  create mode 100644 drivers/gpu/drm/bridge/ite-it6505.c
> 
> diff --git a/drivers/gpu/drm/bridge/Kconfig b/drivers/gpu/drm/bridge/Kconfig
> index e4110d6ca7b3c..25d34d7196004 100644
> --- a/drivers/gpu/drm/bridge/Kconfig
> +++ b/drivers/gpu/drm/bridge/Kconfig
> @@ -74,6 +74,13 @@ config DRM_LONTIUM_LT9611UXC
> HDMI signals
> Please say Y if you have such hardware.
>  
> +config DRM_ITE_IT6505
> + tristate "ITE IT6505 DisplayPort bridge"
> + depends on OF
> + select DRM_KMS_HELPER
> + help
> +   ITE IT6505 DisplayPort bridge chip driver.
> +
>  config DRM_LVDS_CODEC
>   tristate "Transparent LVDS encoders and decoders support"
>   depends on OF
> diff --git a/drivers/gpu/drm/bridge/Makefile b/drivers/gpu/drm/bridge/Makefile
> index 86e7acc76f8d6..2b2f8f0b5b0fa 100644
> --- a/drivers/gpu/drm/bridge/Makefile
> +++ b/drivers/gpu/drm/bridge/Makefile
> @@ -4,6 +4,7 @@ obj-$(CONFIG_DRM_CHRONTEL_CH7033) += chrontel-ch7033.o
>  obj-$(CONFIG_DRM_DISPLAY_CONNECTOR) += display-connector.o
>  obj-$(CONFIG_DRM_LONTIUM_LT9611) += lontium-lt9611.o
>  obj-$(CONFIG_DRM_LONTIUM_LT9611UXC) += lontium-lt9611uxc.o
> +obj-$(CONFIG_DRM_ITE_IT6505) += ite-it6505.o
>  obj-$(CONFIG_DRM_LVDS_CODEC) += lvds-codec.o
>  obj-$(CONFIG_DRM_MEGACHIPS_STDP_GE_B850V3_FW) += 
> megachips-stdp-ge-b850v3-fw.o
>  obj-$(CONFIG_DRM_NXP_PTN3460) += nxp-ptn3460.o
> diff --git a/drivers/gpu/drm/bridge/ite-it6505.c 
> b/drivers/gpu/drm/bridge/ite-it6505.c
> new file mode 100644
> index 0..5e76719a51a4a
> --- /dev/null
> +++ b/drivers/gpu/drm/bridge/ite-it6505.c
> @@ -0,0 +1,3343 @@
> +// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +/*
> + * Copyright (c) 2020, The Linux Foundation. All rights reserved.
> + */
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +
> +#include 
> +
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +
> +#include 
> +
> +#define REG_IC_VER 0x04
> +
> +#define REG_RESET_CTRL 0x05
> +#define VIDEO_RESET BIT(0)
> +#define AUDIO_RESET BIT(1)
> +#define ALL_LOGIC_RESET BIT(2)
> +#define AUX_RESET BIT(3)
> +#define HDCP_RESET BIT(4)
> +
> +#define INT_STATUS_01 0x06
> +#define INT_MASK_01 0x09
> +#define INT_HPD_CHANGE BIT(0)
> +#define INT_RECEIVE_HPD_IRQ BIT(1)
> +#define INT_SCDT_CHANGE BIT(2)
> +#define INT_HDCP_FAIL BIT(3)
> +#define INT_HDCP_DONE BIT(4)
> +
> +#define INT_STATUS_02 0x07
> +#define INT_MASK_02 0x0A
> +#define INT_AUX_CMD_FAIL BIT(0)
> +#define INT_HDCP_KSV_CHECK BIT(1)
> +#define INT_AUDIO_FIFO_ERROR BIT(2)
> +
> +#define INT_STATUS_03 0x08
> +#define INT_MASK_03 0x0B
> +#define INT_LINK_TRAIN_FAIL BIT(4)
> +#define INT_VID_FIFO_ERROR BIT(5)
> +#define INT_IO_LATCH_FIFO_OVERFLOW BIT(7)
> +
> +#define REG_SYSTEM_STS 0x0D
> +#define INT_STS BIT(0)
> +#define HPD_STS BIT(1)
> +#define VIDEO_STB BIT(2)
> +
> +#define REG_LINK_TRA

Re: [PATCH v5 09/12] media: uvcvideo: Implement UVC_QUIRK_PRIVACY_DURING_STREAM

2020-12-22 Thread Laurent Pinchart
't match on VID:PID instead because the same VID:PID is
used in both devices affected by this issue, and devices immune to it ?

> +
>   return 0;
>  }
>  
> diff --git a/drivers/media/usb/uvc/uvc_queue.c 
> b/drivers/media/usb/uvc/uvc_queue.c
> index cd60c6c1749e..e800d491303f 100644
> --- a/drivers/media/usb/uvc/uvc_queue.c
> +++ b/drivers/media/usb/uvc/uvc_queue.c
> @@ -337,9 +337,12 @@ int uvc_dequeue_buffer(struct uvc_video_queue *queue, 
> struct v4l2_buffer *buf,
>  int uvc_queue_streamon(struct uvc_video_queue *queue, enum v4l2_buf_type 
> type)
>  {
>   int ret;
> + struct uvc_streaming *stream = uvc_queue_to_stream(queue);

Please swap the two lines.

>  
>   mutex_lock(>mutex);
>   ret = vb2_streamon(>queue, type);
> + if (stream->dev->quirks & UVC_QUIRK_PRIVACY_DURING_STREAM)
> + uvc_privacy_gpio_event(stream->dev);

Even when vb2_streamon() failed ?

>   mutex_unlock(>mutex);
>  
>   return ret;
> diff --git a/drivers/media/usb/uvc/uvcvideo.h 
> b/drivers/media/usb/uvc/uvcvideo.h
> index 079a407ebba5..32c1ba246d97 100644
> --- a/drivers/media/usb/uvc/uvcvideo.h
> +++ b/drivers/media/usb/uvc/uvcvideo.h
> @@ -209,6 +209,7 @@
>  #define UVC_QUIRK_RESTORE_CTRLS_ON_INIT  0x0400
>  #define UVC_QUIRK_FORCE_Y8   0x0800
>  #define UVC_QUIRK_FORCE_BPP  0x1000
> +#define UVC_QUIRK_PRIVACY_DURING_STREAM  0x2000
>  
>  /* Format flags */
>  #define UVC_FMT_FLAG_COMPRESSED  0x0001
> @@ -826,6 +827,9 @@ extern const struct v4l2_file_operations uvc_fops;
>  int uvc_mc_register_entities(struct uvc_video_chain *chain);
>  void uvc_mc_cleanup_entity(struct uvc_entity *entity);
>  
> +/* Privacy gpio */
> +void uvc_privacy_gpio_event(struct uvc_device *dev);
> +
>  /* Video */
>  int uvc_video_init(struct uvc_streaming *stream);
>  int uvc_video_suspend(struct uvc_streaming *stream);

-- 
Regards,

Laurent Pinchart


Re: [PATCH v5 12/12] media: uvcvideo: use dev_dbg() for uvc_trace()

2020-12-22 Thread Laurent Pinchart
Hi Ricardo,

Thank you for the patch.

On Mon, Dec 21, 2020 at 05:48:19PM +0100, Ricardo Ribalda wrote:
> Instead of calling prink() inside uvc_trace, use dev_dbg(), which add

You're using dev_printk(KERN_DEBUG), which is right, but doesn't match
the commit message.

> context to the output.
> 
> Now that we are at it, regroup the strings so the messages can be easily
> "grepable".
> 
> Suggested-by: Laurent Pinchart 
> Signed-off-by: Ricardo Ribalda 
> ---
>  drivers/media/usb/uvc/uvc_ctrl.c   |  66 ---
>  drivers/media/usb/uvc/uvc_driver.c | 298 +++--
>  drivers/media/usb/uvc/uvc_isight.c |  16 +-
>  drivers/media/usb/uvc/uvc_queue.c  |   9 +-
>  drivers/media/usb/uvc/uvc_status.c |  19 +-
>  drivers/media/usb/uvc/uvc_v4l2.c   |  53 +++--
>  drivers/media/usb/uvc/uvc_video.c  |  72 +++
>  drivers/media/usb/uvc/uvcvideo.h   |  11 +-
>  8 files changed, 291 insertions(+), 253 deletions(-)
> 
> diff --git a/drivers/media/usb/uvc/uvc_ctrl.c 
> b/drivers/media/usb/uvc/uvc_ctrl.c
> index 1f1323a649fb..febe20e2887d 100644
> --- a/drivers/media/usb/uvc/uvc_ctrl.c
> +++ b/drivers/media/usb/uvc/uvc_ctrl.c
> @@ -906,8 +906,8 @@ static struct uvc_control *uvc_find_control(struct 
> uvc_video_chain *chain,
>   }
>  
>   if (ctrl == NULL && !next)
> - uvc_trace(UVC_TRACE_CONTROL, "Control 0x%08x not found.\n",
> - v4l2_id);
> + uvc_trace(chain->dev, UVC_TRACE_CONTROL,
> +   "Control 0x%08x not found.\n", v4l2_id);
>  
>   return ctrl;
>  }
> @@ -1828,9 +1828,9 @@ static int uvc_ctrl_fill_xu_info(struct uvc_device *dev,
>   ret = uvc_query_ctrl(dev, UVC_GET_LEN, ctrl->entity->id, dev->intfnum,
>info->selector, data, 2);
>   if (ret < 0) {
> - uvc_trace(UVC_TRACE_CONTROL,
> + uvc_trace(dev, UVC_TRACE_CONTROL,
> "GET_LEN failed on control %pUl/%u (%d).\n",
> -info->entity, info->selector, ret);
> +   info->entity, info->selector, ret);
>   goto done;
>   }
>  
> @@ -1841,7 +1841,7 @@ static int uvc_ctrl_fill_xu_info(struct uvc_device *dev,
>  
>   ret = uvc_ctrl_get_flags(dev, ctrl, info);
>   if (ret < 0) {
> - uvc_trace(UVC_TRACE_CONTROL,
> + uvc_trace(dev, UVC_TRACE_CONTROL,
> "Failed to get flags for control %pUl/%u (%d).\n",
> info->entity, info->selector, ret);
>   goto done;
> @@ -1849,8 +1849,8 @@ static int uvc_ctrl_fill_xu_info(struct uvc_device *dev,
>  
>   uvc_ctrl_fixup_xu_info(dev, ctrl, info);
>  
> - uvc_trace(UVC_TRACE_CONTROL, "XU control %pUl/%u queried: len %u, "
> -   "flags { get %u set %u auto %u }.\n",
> + uvc_trace(dev, UVC_TRACE_CONTROL,
> +   "XU control %pUl/%u queried: len %u, flags { get %u set %u 
> auto %u }.\n",
> info->entity, info->selector, info->size,
> (info->flags & UVC_CTRL_FLAG_GET_CUR) ? 1 : 0,
> (info->flags & UVC_CTRL_FLAG_SET_CUR) ? 1 : 0,
> @@ -1879,9 +1879,10 @@ static int uvc_ctrl_init_xu_ctrl(struct uvc_device 
> *dev,
>  
>   ret = uvc_ctrl_add_info(dev, ctrl, );
>   if (ret < 0)
> - uvc_trace(UVC_TRACE_CONTROL, "Failed to initialize control "
> -   "%pUl/%u on device %s entity %u\n", info.entity,
> -   info.selector, dev->udev->devpath, ctrl->entity->id);
> + uvc_trace(dev, UVC_TRACE_CONTROL,
> +   "Failed to initialize control %pUl/%u on device %s 
> entity %u\n",
> +   info.entity, info.selector, dev->udev->devpath,
> +   ctrl->entity->id);
>  
>   return ret;
>  }
> @@ -1909,8 +1910,8 @@ int uvc_xu_ctrl_query(struct uvc_video_chain *chain,
>   }
>  
>   if (!found) {
> - uvc_trace(UVC_TRACE_CONTROL, "Extension unit %u not found.\n",
> - xqry->unit);
> + uvc_trace(chain->dev, UVC_TRACE_CONTROL,
> +   "Extension unit %u not found.\n", xqry->unit);
>   return -ENOENT;
>   }
>  
> @@ -1925,8 +1926,9 @@ int uvc_xu_ctrl_query(struct uvc_video_chain *chain,
>   }
>  
>   if (!found) {
> - uvc_trace(UVC_TRACE_CONTROL, "Control %pUl/%u not found.\n",
> -

Re: [PATCH v5 07/12] media: uvcvideo: Implement UVC_EXT_GPIO_UNIT

2020-12-22 Thread Laurent Pinchart
On Tue, Dec 22, 2020 at 10:33:52AM +0200, Laurent Pinchart wrote:
> Hi Ricardo,
> 
> Thank you for the patch.
> 
> On Mon, Dec 21, 2020 at 05:48:14PM +0100, Ricardo Ribalda wrote:
> > Some devices can implement a physical switch to disable the input of the
> > camera on demand. Think of it like an elegant privacy sticker.
> > 
> > The system can read the status of the privacy switch via a GPIO.
> > 
> > It is important to know the status of the switch, e.g. to notify the
> > user when the camera will produce black frames and a videochat
> > application is used.
> > 
> > In some systems, the GPIO is connected to main SoC instead of the
> > camera controller, with the connected reported by the system firmware
> 
> s/connected/connection/
> 
> > (ACPI or DT). In that case, the UVC device isn't aware of the GPIO. We
> > need to implement a virtual entity to handle the GPIO fully on the
> > driver side.
> > 
> > For example, for ACPI-based systems, the GPIO is reported in the USB
> > device object:
> > 
> >   Scope (\_SB.PCI0.XHCI.RHUB.HS07)
> >   {
> > 
> >   /.../
> > 
> > Name (_CRS, ResourceTemplate ()  // _CRS: Current Resource Settings
> > {
> > GpioIo (Exclusive, PullDefault, 0x, 0x, 
> > IoRestrictionOutputOnly,
> > "\\_SB.PCI0.GPIO", 0x00, ResourceConsumer, ,
> > )
> > {   // Pin list
> > 0x0064
> > }
> > })
> > Name (_DSD, Package (0x02)  // _DSD: Device-Specific Data
> > {
> > ToUUID ("daffd814-6eba-4d8c-8a91-bc9bbf4aa301") /* Device 
> > Properties for _DSD */,
> > Package (0x01)
> > {
> > Package (0x02)
> > {
> > "privacy-gpio",
> > Package (0x04)
> > {
> > \_SB.PCI0.XHCI.RHUB.HS07,
> > Zero,
> > Zero,
> > One
> > }
> > }
> > }
> > })
> >   }
> > 
> > Signed-off-by: Ricardo Ribalda 
> > ---
> >  drivers/media/usb/uvc/uvc_ctrl.c   |   7 ++
> >  drivers/media/usb/uvc/uvc_driver.c | 156 +
> >  drivers/media/usb/uvc/uvc_entity.c |   1 +
> >  drivers/media/usb/uvc/uvcvideo.h   |  16 +++
> >  4 files changed, 180 insertions(+)
> > 
> > diff --git a/drivers/media/usb/uvc/uvc_ctrl.c 
> > b/drivers/media/usb/uvc/uvc_ctrl.c
> > index 528254230535..a430fa666897 100644
> > --- a/drivers/media/usb/uvc/uvc_ctrl.c
> > +++ b/drivers/media/usb/uvc/uvc_ctrl.c
> > @@ -1300,6 +1300,10 @@ static void __uvc_ctrl_status_event_work(struct 
> > uvc_device *dev,
> >  
> > mutex_unlock(>ctrl_mutex);
> >  
> > +   /* Events not started by the UVC device. E.g. the GPIO unit */
> > +   if (!w->urb)
> > +   return;
> > +
> > /* Resubmit the URB. */
> > w->urb->interval = dev->int_ep->desc.bInterval;
> > ret = usb_submit_urb(w->urb, GFP_KERNEL);
> > @@ -2317,6 +2321,9 @@ int uvc_ctrl_init_device(struct uvc_device *dev)
> > } else if (UVC_ENTITY_TYPE(entity) == UVC_ITT_CAMERA) {
> > bmControls = entity->camera.bmControls;
> > bControlSize = entity->camera.bControlSize;
> > +   } else if (UVC_ENTITY_TYPE(entity) == UVC_EXT_GPIO_UNIT) {
> > +   bmControls = entity->gpio.bmControls;
> > +   bControlSize = entity->gpio.bControlSize;
> > }
> >  
> > /* Remove bogus/blacklisted controls */
> > diff --git a/drivers/media/usb/uvc/uvc_driver.c 
> > b/drivers/media/usb/uvc/uvc_driver.c
> > index c0c5f75ade40..72516101fdd0 100644
> > --- a/drivers/media/usb/uvc/uvc_driver.c
> > +++ b/drivers/media/usb/uvc/uvc_driver.c
> > @@ -7,6 +7,7 @@
> >   */
> >  
> >  #include 
> > +#include 
> >  #include 
> >  #include 
> >  #include 
> > @@ -1020,6 +1021,7 @@ static int uvc_parse_streaming(struct uvc_device *dev,
> >  }
> >  
> >  static const u8 uvc_camera_guid[16] = UVC_GUID_UVC_CAMERA;
> > +static const u8 uvc_gpio_guid[16] = UVC_GUID_EXT_GPIO_CONTROLLER;
> >  static const u8 uvc_media_transport_input_guid[16] =
> > UVC_GUID_UVC_MEDIA_TRANSPORT_INPUT;
> >  static const u8 uvc_processing_guid[16] = UVC_GUID_UVC_P

Re: [PATCH v5 07/12] media: uvcvideo: Implement UVC_EXT_GPIO_UNIT

2020-12-22 Thread Laurent Pinchart
   "uvc_privacy_gpio", dev);
> + return ret;

No need for a ret variable, you can write

return devm_request_threaded_irq(...);

(unless you want to move the error message here, see below).

> +}
> +
>  /* 
>   * UVC device scan
>   */
> @@ -1915,6 +2051,7 @@ static int uvc_scan_device(struct uvc_device *dev)
>  {
>   struct uvc_video_chain *chain;
>   struct uvc_entity *term;
> + struct uvc_entity *unit;
>  
>   list_for_each_entry(term, >entities, list) {
>   if (!UVC_ENTITY_IS_OTERM(term))
> @@ -1953,6 +2090,13 @@ static int uvc_scan_device(struct uvc_device *dev)
>   return -1;
>   }
>  
> + /* Add GPIO entities to the first chain. */
> + chain = list_first_entry(>chains, struct uvc_video_chain, list);
> + list_for_each_entry(unit, >entities, list) {
> + if (UVC_ENTITY_TYPE(unit) == UVC_EXT_GPIO_UNIT)
> + list_add_tail(>chain, >entities);
> + }
> +
>   return 0;
>  }
>  
> @@ -2285,6 +2429,12 @@ static int uvc_probe(struct usb_interface *intf,
>   goto error;
>   }
>  
> + /* Parse the associated GPIOs. */
> + if (uvc_gpio_parse(dev) < 0) {
> + uvc_trace(UVC_TRACE_PROBE, "Unable to parse UVC GPIOs\n");
> + goto error;
> + }
> +
>   uvc_printk(KERN_INFO, "Found UVC %u.%02x device %s (%04x:%04x)\n",
>   dev->uvc_version >> 8, dev->uvc_version & 0xff,
>   udev->product ? udev->product : "",
> @@ -2329,6 +2479,12 @@ static int uvc_probe(struct usb_interface *intf,
>   "supported.\n", ret);
>   }
>  
> + ret = uvc_gpio_init_irq(dev);
> + if (ret < 0)
> + dev_warn(>udev->dev,
> +  "Unable to request uvc_privacy_gpio irq %d. Continuing 
> wihtout privacy events\n",

s/uvc_privacy_gpio irq/privacy GPIO IRQ/ ?

> +  ret);

This could be moved to uvc_gpio_init_irq(), up to you.

> +
>   uvc_trace(UVC_TRACE_PROBE, "UVC device initialized.\n");
>   usb_enable_autosuspend(udev);
>   return 0;
> diff --git a/drivers/media/usb/uvc/uvc_entity.c 
> b/drivers/media/usb/uvc/uvc_entity.c
> index ca3a9c2eec27..6a9ba5b498db 100644
> --- a/drivers/media/usb/uvc/uvc_entity.c
> +++ b/drivers/media/usb/uvc/uvc_entity.c
> @@ -105,6 +105,7 @@ static int uvc_mc_init_entity(struct uvc_video_chain 
> *chain,
>   case UVC_OTT_DISPLAY:
>   case UVC_OTT_MEDIA_TRANSPORT_OUTPUT:
>   case UVC_EXTERNAL_VENDOR_SPECIFIC:
> + case UVC_EXT_GPIO_UNIT:
>   default:
>   function = MEDIA_ENT_F_V4L2_SUBDEV_UNKNOWN;
>   break;
> diff --git a/drivers/media/usb/uvc/uvcvideo.h 
> b/drivers/media/usb/uvc/uvcvideo.h
> index 6edbf79b2ff1..079a407ebba5 100644
> --- a/drivers/media/usb/uvc/uvcvideo.h
> +++ b/drivers/media/usb/uvc/uvcvideo.h
> @@ -6,6 +6,7 @@
>  #error "The uvcvideo.h header is deprecated, use linux/uvcvideo.h instead."
>  #endif /* __KERNEL__ */
>  
> +#include 
>  #include 
>  #include 
>  #include 
> @@ -37,6 +38,8 @@
>   (UVC_ENTITY_IS_TERM(entity) && \
>   ((entity)->type & 0x8000) == UVC_TERM_OUTPUT)
>  
> +#define UVC_EXT_GPIO_UNIT0x7ffe
> +#define UVC_EXT_GPIO_UNIT_ID 0x100
>  
>  /* 
>   * GUIDs
> @@ -56,6 +59,9 @@
>  #define UVC_GUID_UVC_SELECTOR \
>   {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
>0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02}
> +#define UVC_GUID_EXT_GPIO_CONTROLLER \
> + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
> +  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x03}
>  
>  #define UVC_GUID_FORMAT_MJPEG \
>   { 'M',  'J',  'P',  'G', 0x00, 0x00, 0x10, 0x00, \
> @@ -278,6 +284,8 @@ struct uvc_format_desc {
>   u32 fcc;
>  };
>  
> +struct gpio_desc;
> +

This could be moved a bit up, with the other forward declaration.

>  /* The term 'entity' refers to both UVC units and UVC terminals.
>   *
>   * The type field is either the terminal type (wTerminalType in the terminal
> @@ -353,6 +361,14 @@ struct uvc_entity {
>   u8  *bmControls;
>   u8  *bmControlsType;
>   } extension;
> +
> + struct {
> + u8  bControlSize;
> + u8  *bmControls;
> + struct gpio_desc *gpio_privacy;
> + int irq;
> + atomic_t gpio_privacy_value;
> + } gpio;
>   };
>  
>   u8 bNrInPins;

-- 
Regards,

Laurent Pinchart


Re: [PATCH v5 02/12] media: uvcvideo: Allow more that one asyc_ctrl

2020-12-22 Thread Laurent Pinchart
f --git a/drivers/media/usb/uvc/uvcvideo.h 
> b/drivers/media/usb/uvc/uvcvideo.h
> index 0db6c2e0bd98..afcaf49fad1a 100644
> --- a/drivers/media/usb/uvc/uvcvideo.h
> +++ b/drivers/media/usb/uvc/uvcvideo.h
> @@ -637,6 +637,14 @@ struct uvc_device_info {
>   u32 meta_format;
>  };
>  
> +struct uvc_ctrl_work {
> + struct list_head list;
> + struct urb *urb;
> + struct uvc_video_chain *chain;
> + struct uvc_control *ctrl;
> + u8 data[UVC_MAX_STATUS_SIZE];
> +};
> +
>  struct uvc_device {
>   struct usb_device *udev;
>   struct usb_interface *intf;
> @@ -673,13 +681,10 @@ struct uvc_device {
>   struct input_dev *input;
>   char input_phys[64];
>  
> - struct uvc_ctrl_work {
> - struct work_struct work;
> - struct urb *urb;
> - struct uvc_video_chain *chain;
> - struct uvc_control *ctrl;
> - u8 data[UVC_MAX_STATUS_SIZE];
> - } async_ctrl;
> + /* Async control */
> + struct work_struct async_ctrl_work;
> + struct list_head async_ctrl_list;
> + struct mutex async_ctrl_lock;
>  };
>  
>  enum uvc_handle_state {

-- 
Regards,

Laurent Pinchart


Re: [PATCH v5 01/12] media: uvcvideo: Fix race condition handling events

2020-12-22 Thread Laurent Pinchart
Hi Ricardo,

Thank you for the patch.

On Mon, Dec 21, 2020 at 05:48:08PM +0100, Ricardo Ribalda wrote:
> The control and its data needs to be copied to the workqueue at the same
> time to avoid half-updates of the events.
> This is, events reported to userspace were the control id does not match
> its value.

Actually, after discussing this with you on IRC, I'm not sure there's a
problem. The URB is resubmitted by uvc_ctrl_status_event_work(), so the
data shouldn't be overwritten before it is processed.

> Signed-off-by: Ricardo Ribalda 
> ---
>  drivers/media/usb/uvc/uvc_ctrl.c | 2 +-
>  drivers/media/usb/uvc/uvcvideo.h | 2 +-
>  2 files changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/media/usb/uvc/uvc_ctrl.c 
> b/drivers/media/usb/uvc/uvc_ctrl.c
> index 011e69427b7c..aa18dcdf8165 100644
> --- a/drivers/media/usb/uvc/uvc_ctrl.c
> +++ b/drivers/media/usb/uvc/uvc_ctrl.c
> @@ -1332,7 +1332,7 @@ bool uvc_ctrl_status_event(struct urb *urb, struct 
> uvc_video_chain *chain,
>   return false;
>   }
>  
> - w->data = data;
> + memcpy(w->data, data, ctrl->info.size);
>   w->urb = urb;
>   w->chain = chain;
>   w->ctrl = ctrl;
> diff --git a/drivers/media/usb/uvc/uvcvideo.h 
> b/drivers/media/usb/uvc/uvcvideo.h
> index a3dfacf069c4..0db6c2e0bd98 100644
> --- a/drivers/media/usb/uvc/uvcvideo.h
> +++ b/drivers/media/usb/uvc/uvcvideo.h
> @@ -678,7 +678,7 @@ struct uvc_device {
>   struct urb *urb;
>   struct uvc_video_chain *chain;
>   struct uvc_control *ctrl;
> -     const void *data;
> + u8 data[UVC_MAX_STATUS_SIZE];
>   } async_ctrl;
>  };
>  

-- 
Regards,

Laurent Pinchart


Re: [PATCH 11/14] dt-bindings: display: bridge: Add i.MX8qm/qxp LVDS display bridge binding

2020-12-21 Thread Laurent Pinchart
Hi Liu,

On Tue, Dec 22, 2020 at 09:36:37AM +0200, Laurent Pinchart wrote:
> On Thu, Dec 17, 2020 at 05:59:30PM +0800, Liu Ying wrote:
> > This patch adds bindings for i.MX8qm/qxp LVDS display bridge(LDB).
> > 
> > Signed-off-by: Liu Ying 
> > ---
> >  .../bindings/display/bridge/fsl,imx8qxp-ldb.yaml   | 185 
> > +
> >  1 file changed, 185 insertions(+)
> >  create mode 100644 
> > Documentation/devicetree/bindings/display/bridge/fsl,imx8qxp-ldb.yaml
> > 
> > diff --git 
> > a/Documentation/devicetree/bindings/display/bridge/fsl,imx8qxp-ldb.yaml 
> > b/Documentation/devicetree/bindings/display/bridge/fsl,imx8qxp-ldb.yaml
> > new file mode 100644
> > index ..4e5ff6f
> > --- /dev/null
> > +++ b/Documentation/devicetree/bindings/display/bridge/fsl,imx8qxp-ldb.yaml
> > @@ -0,0 +1,185 @@
> > +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> > +%YAML 1.2
> > +---
> > +$id: http://devicetree.org/schemas/display/bridge/fsl,imx8qxp-ldb.yaml#
> > +$schema: http://devicetree.org/meta-schemas/core.yaml#
> > +
> > +title: Freescale i.MX8qm/qxp LVDS Display Bridge
> > +
> > +maintainers:
> > +  - Liu Ying 
> > +
> > +description: |
> > +  The Freescale i.MX8qm/qxp LVDS Display Bridge(LDB) has two channels.
> > +
> > +  For i.MX8qxp LDB, each channel supports up to 24bpp parallel input color
> > +  format and can map the input to VESA or JEIDA standards.  The two 
> > channels
> > +  cannot be used simultaneously, that is to say, the user should pick one 
> > of
> > +  them to use.  Two LDB channels from two LDB instances can work together 
> > in
> > +  LDB split mode to support a dual link LVDS display.  The channel indexes
> > +  have to be different.  Channel0 outputs odd pixels and channel1 outputs
> > +  even pixels.
> 
> In this case, does the display controller output odd pixels and even
> pixels separately to the two LVDS channels, with each channel
> effectively be a separate LVDS encoder ? Could you give an example of DT
> integration for dual-link LVDS support, with the display controller, two
> LDB instances, and a dual-link LVDS panel ?

I also can't find any mention of the LDB in IMX8MDQLQRM or IMX8DQXPRM.
Am I missing something ?

> > +
> > +  For i.MX8qm LDB, each channel additionally supports up to 30bpp parallel
> > +  input color format.  The two channels can be used simultaneously, either
> > +  in dual mode or split mode.  In dual mode, the two channels output 
> > identical
> > +  data.  In split mode, channel0 outputs odd pixels and channel1 outputs 
> > even
> > +  pixels.
> > +
> > +properties:
> > +  compatible:
> > +enum:
> > +  - fsl,imx8qm-ldb
> > +  - fsl,imx8qxp-ldb
> > +
> > +  "#address-cells":
> > +const: 1
> > +
> > +  "#size-cells":
> > +const: 0
> > +
> > +  clocks:
> > +items:
> > +  - description: pixel clock
> > +  - description: bypass clock
> > +
> > +  clock-names:
> > +items:
> > +  - const: pixel
> > +  - const: bypass
> > +
> > +  power-domains:
> > +maxItems: 1
> > +
> > +  fsl,syscon:
> > +$ref: /schemas/types.yaml#/definitions/phandle
> > +description: |
> > +  A phandle which points to Control and Status Registers(CSR) module.
> > +
> > +  fsl,companion-ldb:
> > +$ref: /schemas/types.yaml#/definitions/phandle
> > +description: |
> > +  A phandle which points to companion LDB which is used in LDB split 
> > mode.
> > +
> > +patternProperties:
> > +  "^channel@[0-1]$":
> > +type: object
> > +description: Represents a channel of LDB.
> > +
> > +properties:
> > +  "#address-cells":
> > +const: 1
> > +
> > +  "#size-cells":
> > +const: 0
> > +
> > +  reg:
> > +description: The channel index.
> > +enum: [ 0, 1 ]
> > +
> > +  phys:
> > +description: A phandle to the phy module representing the LVDS PHY.
> > +maxItems: 1
> > +
> > +  phy-names:
> > +const: lvds_phy
> > +
> > +  port@0:
> > +type: object
> > +description: Input port of the channel.
> > +
> > +properties:
> > +  reg:
> > +const: 0
> > +
> > +required:
> > +  - reg
> > +

Re: [PATCH 11/14] dt-bindings: display: bridge: Add i.MX8qm/qxp LVDS display bridge binding

2020-12-21 Thread Laurent Pinchart
; +const: fsl,imx8qm-ldb
> +then:
> +  properties:
> +fsl,companion-ldb: false
> +
> +additionalProperties: false
> +
> +examples:
> +  - |
> +#include 
> +ldb {
> +#address-cells = <1>;
> +#size-cells = <0>;
> +compatible = "fsl,imx8qxp-ldb";
> +clocks = < IMX_SC_R_LVDS_0 IMX_SC_PM_CLK_MISC2>,
> + < IMX_SC_R_LVDS_0 IMX_SC_PM_CLK_BYPASS>;
> +clock-names = "pixel", "bypass";
> +power-domains = < IMX_SC_R_LVDS_0>;
> +fsl,syscon = <_lvds_0_csr>;
> +
> +channel@0 {
> +#address-cells = <1>;
> +#size-cells = <0>;
> +reg = <0>;
> +phys = <_lvds_0_phy>;
> +phy-names = "lvds_phy";
> +
> +port@0 {
> +    reg = <0>;
> +
> +mipi_lvds_0_ldb_ch0_mipi_lvds_0_pxl2dpi: endpoint {
> +remote-endpoint = 
> <_lvds_0_pxl2dpi_mipi_lvds_0_ldb_ch0>;
> +};
> +};
> +};
> +
> +channel@1 {
> +#address-cells = <1>;
> +#size-cells = <0>;
> +reg = <1>;
> +phys = <_lvds_0_phy>;
> +phy-names = "lvds_phy";
> +
> +port@0 {
> +reg = <0>;
> +
> +mipi_lvds_0_ldb_ch1_mipi_lvds_0_pxl2dpi: endpoint {
> +remote-endpoint = 
> <_lvds_0_pxl2dpi_mipi_lvds_0_ldb_ch1>;
> +};
> +};
> +};
> +};

-- 
Regards,

Laurent Pinchart


Re: [PATCH 06/14] dt-bindings: display: bridge: Add i.MX8qm/qxp display pixel link binding

2020-12-21 Thread Laurent Pinchart
Hi Liu,

Thank you for the patch.

On Thu, Dec 17, 2020 at 05:59:25PM +0800, Liu Ying wrote:
> This patch adds bindings for i.MX8qm/qxp display pixel link.
> 
> Signed-off-by: Liu Ying 
> ---
>  .../display/bridge/fsl,imx8qxp-pixel-link.yaml | 128 
> +
>  1 file changed, 128 insertions(+)
>  create mode 100644 
> Documentation/devicetree/bindings/display/bridge/fsl,imx8qxp-pixel-link.yaml
> 
> diff --git 
> a/Documentation/devicetree/bindings/display/bridge/fsl,imx8qxp-pixel-link.yaml
>  
> b/Documentation/devicetree/bindings/display/bridge/fsl,imx8qxp-pixel-link.yaml
> new file mode 100644
> index ..fd24a0e
> --- /dev/null
> +++ 
> b/Documentation/devicetree/bindings/display/bridge/fsl,imx8qxp-pixel-link.yaml
> @@ -0,0 +1,128 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: 
> http://devicetree.org/schemas/display/bridge/fsl,imx8qxp-pixel-link.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Freescale i.MX8qm/qxp Display Pixel Link
> +
> +maintainers:
> +  - Liu Ying 
> +
> +description: |
> +  The Freescale i.MX8qm/qxp Display Pixel Link(DPL) forms a standard
> +  asynchronous linkage between pixel sources(display controller or
> +  camera module) and pixel consumers(imaging or displays).
> +  It consists of two distinct functions, a pixel transfer function and a
> +  control interface.  Multiple pixel channels can exist per one control 
> channel.
> +  This binding documentation is only for pixel links whose pixel sources are
> +  display controllers.
> +
> +properties:
> +  compatible:
> +enum:
> +  - fsl,imx8qm-dc-pixel-link
> +  - fsl,imx8qxp-dc-pixel-link
> +
> +  ports:
> +type: object
> +description: |
> +  A node containing pixel link input & output port nodes with endpoint
> +  definitions as documented in
> +  Documentation/devicetree/bindings/media/video-interfaces.txt
> +  Documentation/devicetree/bindings/graph.txt

With Rob's patch that convert both of these to YAML, I think you can
drop the references to these documents, and use

  $ref: /schemas/graph.yaml#/properties/ports

in the ports node, and

  $ref: /schemas/graph.yaml#/$defs/port-base
  unevaluatedProperties: false

in the port nodes, dropping the type property. You will also be able to
drop

  additionalProperties: false

for the ports node.

> +
> +properties:
> +  '#address-cells':
> +const: 1
> +
> +  '#size-cells':
> +const: 0
> +
> +  port@0:
> +type: object
> +description: The pixel link input port node from upstream video 
> source.
> +
> +properties:
> +  reg:
> +const: 0
> +
> +required:
> +  - reg
> +
> +patternProperties:
> +  "^port@[1-4]$":
> +type: object
> +description: The pixel link output port node to downstream bridge.
> +
> +properties:
> +  reg:
> +enum: [ 1, 2, 3, 4 ]
> +
> +required:
> +  - reg
> +
> +required:
> +  - "#address-cells"
> +  - "#size-cells"
> +  - port@0
> +
> +anyOf:
> +  - required:
> +  - port@1
> +  - required:
> +  - port@2
> +  - required:
> +  - port@3
> +  - required:
> +  - port@4

Do all DPL instances have four output ports ? If so I would make all of
them mandatory, as they describe the hardware. They can be left without
any endpoing if they're not connected to anything.

> +
> +additionalProperties: false
> +
> +required:
> +  - compatible
> +  - ports
> +
> +additionalProperties: false
> +
> +examples:
> +  - |
> +dc0-pixel-link0 {
> +compatible = "fsl,imx8qxp-dc-pixel-link";
> +
> +ports {
> +#address-cells = <1>;
> +#size-cells = <0>;
> +
> +/* from dc0 pixel combiner channel0 */
> +port@0 {
> +reg = <0>;
> +
> +dc0_pixel_link0_dc0_pixel_combiner_ch0: endpoint {
> +remote-endpoint = 
> <_pixel_combiner_ch0_dc0_pixel_link0>;
> +};
> +};
> +
> +/* to PXL2DPIs in MIPI/LVDS combo subsystems */
> +port@1 {
> +#address-cells = <1>;
> +#size-cells = <0>;
> +reg = <1>;
> +
> +dc0_pixel_link0_mipi_lvds_0_pxl2dpi: endpoint@0 {
> +    reg = <0>;
> +remote-endpoint = <_lvds_0_pxl2dpi_dc0_pixel_link0>;
> +};
> +
> +dc0_pixel_link0_mipi_lvds_1_pxl2dpi: endpoint@1 {
> +reg = <1>;
> +remote-endpoint = <_lvds_1_pxl2dpi_dc0_pixel_link0>;
> +};
> +};
> +
> +/* to imaging subsystem */
> +port@4 {
> +reg = <4>;
> +};
> +};
> +};

-- 
Regards,

Laurent Pinchart


Re: [PATCH] dt-bindings: Drop unnecessary *-supply schemas properties

2020-12-21 Thread Laurent Pinchart
Hi Rob,

Thank you for the patch.

On Mon, Dec 21, 2020 at 04:46:59PM -0700, Rob Herring wrote:
> *-supply properties are always a single phandle, so binding schemas
> don't need a type $ref nor 'maxItems'.
> 
> A meta-schema check for this is pending once these existing cases are
> fixed.
> 
> Cc: Jonathan Cameron 
> Cc: Dmitry Torokhov 
> Cc: Laurent Pinchart 
> Cc: Mauro Carvalho Chehab 
> Cc: Sakari Ailus 
> Cc: Lee Jones 
> Cc: Mark Brown 
> Cc: Maxime Ripard 
> Cc: dri-de...@lists.freedesktop.org
> Cc: linux-...@vger.kernel.org
> Cc: linux-in...@vger.kernel.org
> Cc: linux-me...@vger.kernel.org
> Signed-off-by: Rob Herring 
> ---
>  Documentation/devicetree/bindings/display/bridge/anx6345.yaml | 2 --
>  .../devicetree/bindings/display/bridge/ite,it6505.yaml| 2 --
>  .../devicetree/bindings/display/bridge/lvds-codec.yaml| 3 +--
>  Documentation/devicetree/bindings/display/bridge/ps8640.yaml  | 2 --
>  .../devicetree/bindings/display/bridge/simple-bridge.yaml | 1 -
>  .../bindings/display/bridge/thine,thc63lvd1024.yaml   | 1 -
>  .../devicetree/bindings/display/bridge/toshiba,tc358775.yaml  | 2 --
>  Documentation/devicetree/bindings/iio/adc/lltc,ltc2496.yaml   | 4 +---
>  .../devicetree/bindings/iio/humidity/ti,hdc2010.yaml  | 3 +--
>  .../devicetree/bindings/input/fsl,mpr121-touchkey.yaml| 3 +--
>  .../devicetree/bindings/input/touchscreen/edt-ft5x06.yaml | 3 +--
>  .../devicetree/bindings/media/i2c/maxim,max9286.yaml  | 1 -
>  Documentation/devicetree/bindings/media/i2c/mipi-ccs.yaml | 3 ---
>  Documentation/devicetree/bindings/media/i2c/sony,imx214.yaml  | 3 ---
>  Documentation/devicetree/bindings/media/i2c/sony,imx274.yaml  | 3 ---
>  Documentation/devicetree/bindings/mfd/st,stmfx.yaml   | 3 +--
>  .../devicetree/bindings/regulator/anatop-regulator.yaml   | 1 -
>  17 files changed, 6 insertions(+), 34 deletions(-)
> 
> diff --git a/Documentation/devicetree/bindings/display/bridge/anx6345.yaml 
> b/Documentation/devicetree/bindings/display/bridge/anx6345.yaml
> index 8c0e4f285fbc..fccd63521a8c 100644
> --- a/Documentation/devicetree/bindings/display/bridge/anx6345.yaml
> +++ b/Documentation/devicetree/bindings/display/bridge/anx6345.yaml
> @@ -26,11 +26,9 @@ properties:
>  description: GPIO connected to active low reset
>  
>dvdd12-supply:
> -maxItems: 1
>  description: Regulator for 1.2V digital core power.
>  
>dvdd25-supply:
> -maxItems: 1
>  description: Regulator for 2.5V digital core power.
>  
>ports:
> diff --git a/Documentation/devicetree/bindings/display/bridge/ite,it6505.yaml 
> b/Documentation/devicetree/bindings/display/bridge/ite,it6505.yaml
> index efbb3d0117dc..02cfc0a3b550 100644
> --- a/Documentation/devicetree/bindings/display/bridge/ite,it6505.yaml
> +++ b/Documentation/devicetree/bindings/display/bridge/ite,it6505.yaml
> @@ -35,11 +35,9 @@ properties:
>  maxItems: 1
>  
>ovdd-supply:
> -maxItems: 1
>  description: I/O voltage
>  
>pwr18-supply:
> -maxItems: 1
>  description: core voltage
>  
>interrupts:
> diff --git a/Documentation/devicetree/bindings/display/bridge/lvds-codec.yaml 
> b/Documentation/devicetree/bindings/display/bridge/lvds-codec.yaml
> index e5e3c72630cf..66a14d60ce1d 100644
> --- a/Documentation/devicetree/bindings/display/bridge/lvds-codec.yaml
> +++ b/Documentation/devicetree/bindings/display/bridge/lvds-codec.yaml
> @@ -79,8 +79,7 @@ properties:
>The GPIO used to control the power down line of this device.
>  maxItems: 1
>  
> -  power-supply:
> -maxItems: 1
> +  power-supply: true
>  
>  required:
>- compatible
> diff --git a/Documentation/devicetree/bindings/display/bridge/ps8640.yaml 
> b/Documentation/devicetree/bindings/display/bridge/ps8640.yaml
> index 7e27cfcf770d..763c7909473e 100644
> --- a/Documentation/devicetree/bindings/display/bridge/ps8640.yaml
> +++ b/Documentation/devicetree/bindings/display/bridge/ps8640.yaml
> @@ -35,11 +35,9 @@ properties:
>  description: GPIO connected to active low reset.
>  
>vdd12-supply:
> -maxItems: 1
>  description: Regulator for 1.2V digital core power.
>  
>vdd33-supply:
> -maxItems: 1
>  description: Regulator for 3.3V digital core power.
>  
>ports:
> diff --git 
> a/Documentation/devicetree/bindings/display/bridge/simple-bridge.yaml 
> b/Documentation/devicetree/bindings/display/bridge/simple-bridge.yaml
> index 3ddb35fcf0a2..64e8a1c24b40 100644
> --- a/Documentation/devicetree/bindings/display/bridge/simple-bridge.yaml
> +++ b/Documentation/devicetree/bindings/display/bridge/simple-bridge.yaml

Re: [PATCH] dt-bindings: Drop redundant maxItems/items

2020-12-21 Thread Laurent Pinchart
Hi Rob,

Thank you for the patch.

On Mon, Dec 21, 2020 at 09:06:45PM -0700, Rob Herring wrote:
> 'maxItems' equal to the 'items' list length is redundant. 'maxItems' is
> preferred for a single entry while greater than 1 should have an 'items'
> list.
> 
> A meta-schema check for this is pending once these existing cases are
> fixed.
> 
> Cc: Laurent Pinchart 
> Cc: Vinod Koul 
> Cc: Mark Brown 
> Cc: Greg Kroah-Hartman 
> Cc: Jassi Brar 
> Cc: dri-de...@lists.freedesktop.org
> Cc: dmaeng...@vger.kernel.org
> Cc: alsa-de...@alsa-project.org
> Cc: linux-...@vger.kernel.org
> Signed-off-by: Rob Herring 

Reviewed-by: Laurent Pinchart 

> ---
>  .../devicetree/bindings/display/xlnx/xlnx,zynqmp-dpsub.yaml| 1 -
>  Documentation/devicetree/bindings/dma/renesas,rcar-dmac.yaml   | 1 -
>  Documentation/devicetree/bindings/mailbox/arm,mhu.yaml | 1 -
>  .../devicetree/bindings/sound/nvidia,tegra30-hda.yaml  | 2 --
>  Documentation/devicetree/bindings/usb/renesas,usb-xhci.yaml| 1 -
>  Documentation/devicetree/bindings/usb/renesas,usbhs.yaml   | 3 ---
>  6 files changed, 9 deletions(-)
> 
> diff --git 
> a/Documentation/devicetree/bindings/display/xlnx/xlnx,zynqmp-dpsub.yaml 
> b/Documentation/devicetree/bindings/display/xlnx/xlnx,zynqmp-dpsub.yaml
> index 7b9d468c3e52..403d57977ee7 100644
> --- a/Documentation/devicetree/bindings/display/xlnx/xlnx,zynqmp-dpsub.yaml
> +++ b/Documentation/devicetree/bindings/display/xlnx/xlnx,zynqmp-dpsub.yaml
> @@ -98,7 +98,6 @@ properties:
>  maxItems: 1
>  
>dmas:
> -maxItems: 4
>  items:
>- description: Video layer, plane 0 (RGB or luma)
>- description: Video layer, plane 1 (U/V or U)
> diff --git a/Documentation/devicetree/bindings/dma/renesas,rcar-dmac.yaml 
> b/Documentation/devicetree/bindings/dma/renesas,rcar-dmac.yaml
> index b548e4723936..c07eb6f2fc8d 100644
> --- a/Documentation/devicetree/bindings/dma/renesas,rcar-dmac.yaml
> +++ b/Documentation/devicetree/bindings/dma/renesas,rcar-dmac.yaml
> @@ -73,7 +73,6 @@ properties:
>  maxItems: 1
>  
>clock-names:
> -maxItems: 1
>  items:
>- const: fck
>  
> diff --git a/Documentation/devicetree/bindings/mailbox/arm,mhu.yaml 
> b/Documentation/devicetree/bindings/mailbox/arm,mhu.yaml
> index d43791a2dde7..d07eb00b97c8 100644
> --- a/Documentation/devicetree/bindings/mailbox/arm,mhu.yaml
> +++ b/Documentation/devicetree/bindings/mailbox/arm,mhu.yaml
> @@ -61,7 +61,6 @@ properties:
>- description: low-priority non-secure
>- description: high-priority non-secure
>- description: Secure
> -maxItems: 3
>  
>clocks:
>  maxItems: 1
> diff --git a/Documentation/devicetree/bindings/sound/nvidia,tegra30-hda.yaml 
> b/Documentation/devicetree/bindings/sound/nvidia,tegra30-hda.yaml
> index e543a6123792..b55775e21de6 100644
> --- a/Documentation/devicetree/bindings/sound/nvidia,tegra30-hda.yaml
> +++ b/Documentation/devicetree/bindings/sound/nvidia,tegra30-hda.yaml
> @@ -44,7 +44,6 @@ properties:
>  maxItems: 3
>  
>clock-names:
> -maxItems: 3
>  items:
>- const: hda
>- const: hda2hdmi
> @@ -54,7 +53,6 @@ properties:
>  maxItems: 3
>  
>reset-names:
> -maxItems: 3
>  items:
>- const: hda
>- const: hda2hdmi
> diff --git a/Documentation/devicetree/bindings/usb/renesas,usb-xhci.yaml 
> b/Documentation/devicetree/bindings/usb/renesas,usb-xhci.yaml
> index 0f078bd0a3e5..22603256ddf8 100644
> --- a/Documentation/devicetree/bindings/usb/renesas,usb-xhci.yaml
> +++ b/Documentation/devicetree/bindings/usb/renesas,usb-xhci.yaml
> @@ -51,7 +51,6 @@ properties:
>  maxItems: 1
>  
>phy-names:
> -maxItems: 1
>  items:
>- const: usb
>  
> diff --git a/Documentation/devicetree/bindings/usb/renesas,usbhs.yaml 
> b/Documentation/devicetree/bindings/usb/renesas,usbhs.yaml
> index 737c1f47b7de..54c361d4a7af 100644
> --- a/Documentation/devicetree/bindings/usb/renesas,usbhs.yaml
> +++ b/Documentation/devicetree/bindings/usb/renesas,usbhs.yaml
> @@ -74,11 +74,8 @@ properties:
>  
>phys:
>  maxItems: 1
> -items:
> -  - description: phandle + phy specifier pair.
>  
>phy-names:
> -maxItems: 1
>  items:
>- const: usb
>  

-- 
Regards,

Laurent Pinchart


Re: [PATCH v4 9/9] media: uvcvideo: Implement UVC_QUIRK_PRIVACY_DURING_STREAM

2020-12-20 Thread Laurent Pinchart
Hi Ricardo,

On Mon, Dec 21, 2020 at 02:10:18AM +0100, Ricardo Ribalda wrote:
> On Sun, Dec 20, 2020 at 6:22 PM Laurent Pinchart wrote:
> > On Tue, Dec 15, 2020 at 04:44:39PM +0100, Ricardo Ribalda wrote:
> > > Some devices, can only read the privacy_pin if the device is
> > > streaming.
> >
> > :-(
> 
> :"-(
> 
> > > This patch implement a quirk for such devices, in order to avoid invalid
> > > reads and/or spurious events.
> > >
> > > Signed-off-by: Ricardo Ribalda 
> > > ---
> > >  drivers/media/usb/uvc/uvc_driver.c | 97 ++
> > >  drivers/media/usb/uvc/uvc_queue.c  |  3 +
> > >  drivers/media/usb/uvc/uvcvideo.h   |  6 ++
> > >  3 files changed, 94 insertions(+), 12 deletions(-)
> > >
> > > diff --git a/drivers/media/usb/uvc/uvc_driver.c 
> > > b/drivers/media/usb/uvc/uvc_driver.c
> > > index e49491250e87..61313019e226 100644
> > > --- a/drivers/media/usb/uvc/uvc_driver.c
> > > +++ b/drivers/media/usb/uvc/uvc_driver.c
> > > @@ -7,6 +7,7 @@
> > >   */
> > >
> > >  #include 
> > > +#include 
> > >  #include 
> > >  #include 
> > >  #include 
> > > @@ -1471,13 +1472,39 @@ static int uvc_parse_control(struct uvc_device 
> > > *dev)
> > >   return 0;
> > >  }
> > >
> > > +static bool uvc_ext_gpio_is_streaming(struct uvc_device *dev)
> > > +{
> > > + struct uvc_streaming *streaming;
> > > +
> > > + list_for_each_entry(streaming, >streams, list) {
> > > + if (uvc_queue_streaming(>queue))
> > > + return true;
> > > + }
> > > +
> > > + return false;
> > > +}
> > > +
> > > +/* Update the cached value and return true if it has changed */
> > > +static bool uvc_gpio_update_value(struct uvc_entity *unit, u8 *new_val)
> > > +{
> > > + *new_val = gpiod_get_value(unit->gpio.gpio_privacy);
> > > +
> > > + return atomic_xchg(>gpio.gpio_privacy_value, *new_val) !=
> > > +   
> > > *new_val;
> >
> > That's a weird indentation. Also, as the left hand side modifies
> > *new_val, does C guarantee the order in which the two operands to != are
> > evaluated ? Could the code be written in an easier to read way ?
> >
> > > +}
> > > +
> > >  static int uvc_gpio_get_cur(struct uvc_device *dev, struct uvc_entity 
> > > *entity,
> > >   u8 cs, void *data, u16 size)
> > >  {
> > >   if (cs != UVC_CT_PRIVACY_CONTROL || size < 1)
> > >   return -EINVAL;
> > >
> > > - *(uint8_t *)data = gpiod_get_value(entity->gpio.gpio_privacy);
> > > + if ((dev->quirks & UVC_QUIRK_PRIVACY_DURING_STREAM) &&
> > > + !uvc_ext_gpio_is_streaming(dev))
> > > + return -EBUSY;
> > > +
> > > + uvc_gpio_update_value(entity, (uint8_t *)data);
> > > +
> > >   return 0;
> > >  }
> > >
> > > @@ -1491,26 +1518,69 @@ static int uvc_gpio_get_info(struct uvc_device 
> > > *dev, struct uvc_entity *entity,
> > >   return 0;
> > >  }
> > >
> > > -static irqreturn_t uvc_privacy_gpio_irq(int irq, void *data)
> > > +static struct uvc_entity *uvc_find_ext_gpio_unit(struct uvc_device *dev)
> > >  {
> > > - struct uvc_device *dev = data;
> > > - struct uvc_video_chain *chain;
> > >   struct uvc_entity *unit;
> > > - u8 value;
> > >
> > > - /* GPIO entities are always on the first chain */
> > > - chain = list_first_entry(>chains, struct uvc_video_chain, 
> > > list);
> > >   list_for_each_entry(unit, >entities, list) {
> > > - if (UVC_ENTITY_TYPE(unit) != UVC_EXT_GPIO_UNIT)
> > > - continue;
> > > - value = gpiod_get_value(unit->gpio.gpio_privacy);
> > > - uvc_ctrl_status_event(NULL, chain, unit->controls, );
> > > - return IRQ_HANDLED;
> > > + if (UVC_ENTITY_TYPE(unit) == UVC_EXT_GPIO_UNIT)
> > > + return unit;
> > >   }
> > >
> > > + return unit;
> > > +}
> > > +
> > > +void uvc_privacy_gpio_event(struct uvc_device *dev)

Re: [PATCH v4 5/9] media: uvcvideo: Implement UVC_EXT_GPIO_UNIT

2020-12-20 Thread Laurent Pinchart
Hi Ricardo,

On Sun, Dec 20, 2020 at 11:56:12PM +0100, Ricardo Ribalda wrote:
> On Sun, Dec 20, 2020 at 5:49 PM Laurent Pinchart wrote:
> > On Tue, Dec 15, 2020 at 04:44:35PM +0100, Ricardo Ribalda wrote:
> > > Some devices can implement a physical switch to disable the input of the
> > > camera on demand. Think of it like an elegant privacy sticker.
> > >
> > > The system can read the status of the privacy switch via a GPIO.
> > >
> > > It is important to know the status of the switch, e.g. to notify the
> > > user when the camera will produce black frames and a videochat
> > > application is used.
> > >
> > > Since the uvc device is not aware of this pin (and it should't), we need
> >
> > s/should't/shouldn't/
> >
> > But I don't agree, if this is part of the camera, it should be
> > implemented in the camera firmware. I understand that it's not possible
> > (or desirable) with the hardware architecture you're dealing with
> > though. How about
> >
> > "In some systems, the GPIO is connected to main SoC instead of the
> > camera controller, with the connected reported by the system firmware
> > (ACPI or DT). In that case, the UVC device isn't aware of the GPIO. We
> > need to implement a virtual entity to handle the GPIO fully on the
> > driver side.
> >
> > For example, for ACPI-based systems, the GPIO is reported in the USB
> > device object:"
> >
> > > to implement a virtual entity that can interact with such pin.
> > >
> > > The location of the GPIO is specified via acpi or DT. on the usb device 
> > > Eg:
> > >
> > >   Scope (\_SB.PCI0.XHCI.RHUB.HS07)
> > >   {
> > >
> > > /.../
> > >
> > > Name (_CRS, ResourceTemplate ()  // _CRS: Current Resource Settings
> > > {
> > > GpioIo (Exclusive, PullDefault, 0x, 0x, 
> > > IoRestrictionOutputOnly,
> > > "\\_SB.PCI0.GPIO", 0x00, ResourceConsumer, ,
> > > )
> > > {   // Pin list
> > > 0x0064
> > > }
> > > })
> > > Name (_DSD, Package (0x02)  // _DSD: Device-Specific Data
> > > {
> > > ToUUID ("daffd814-6eba-4d8c-8a91-bc9bbf4aa301") /* Device 
> > > Properties for _DSD */,
> > > Package (0x01)
> > > {
> > > Package (0x02)
> > > {
> > > "privacy-gpio",
> > > Package (0x04)
> > > {
> > > \_SB.PCI0.XHCI.RHUB.HS07,
> > > Zero,
> > > Zero,
> > > One
> > > }
> > > }
> > > }
> > > })
> > >   }
> > >
> > > Signed-off-by: Ricardo Ribalda 
> > > ---
> > >  drivers/media/usb/uvc/uvc_ctrl.c   |   6 ++
> > >  drivers/media/usb/uvc/uvc_driver.c | 106 +
> > >  drivers/media/usb/uvc/uvcvideo.h   |  12 
> > >  3 files changed, 124 insertions(+)
> > >
> > > diff --git a/drivers/media/usb/uvc/uvc_ctrl.c 
> > > b/drivers/media/usb/uvc/uvc_ctrl.c
> > > index 531816762892..53da1d984883 100644
> > > --- a/drivers/media/usb/uvc/uvc_ctrl.c
> > > +++ b/drivers/media/usb/uvc/uvc_ctrl.c
> > > @@ -1302,6 +1302,9 @@ static void uvc_ctrl_status_event_work(struct 
> > > work_struct *work)
> > >
> > >   mutex_unlock(>ctrl_mutex);
> > >
> > > + if (!w->urb)
> > > + return;
> >
> > A small comment to explain why would be useful.
> >
> > > +
> > >   /* Resubmit the URB. */
> > >   w->urb->interval = dev->int_ep->desc.bInterval;
> > >   ret = usb_submit_urb(w->urb, GFP_KERNEL);
> > > @@ -2286,6 +2289,9 @@ int uvc_ctrl_init_device(struct uvc_device *dev)
> > >   } else if (UVC_ENTITY_TYPE(entity) == UVC_ITT_CAMERA) {
> > >   bmControls = entity->camera.bmControls;
> > >   bControlSize = entity->camera.bControlSize;
> > > + } else if (UVC_ENTITY_TYPE(entity) == UVC_EXT_GPIO_UNIT) {
> > > + bmControls = entity->gpio.bmControls;
> > > + bControlSize = entity->gpio.bControlSize;
> > > 

Re: [PATCH] drm: bridge: adv7511: Remove redundant null check before clk_disable_unprepare

2020-12-20 Thread Laurent Pinchart
Hi Xu Wang,

Thank you for the patch.

On Fri, Nov 27, 2020 at 09:18:29AM +, Xu Wang wrote:
> Because clk_disable_unprepare() already checked NULL clock parameter,
> so the additional check is unnecessary, just remove them.
> 
> Signed-off-by: Xu Wang 

Reviewed-by: Laurent Pinchart 

> ---
>  drivers/gpu/drm/bridge/adv7511/adv7511_drv.c | 6 ++
>  1 file changed, 2 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c 
> b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
> index a0d392c338da..76555ae64e9c 100644
> --- a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
> +++ b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
> @@ -1292,8 +1292,7 @@ static int adv7511_probe(struct i2c_client *i2c, const 
> struct i2c_device_id *id)
>  
>  err_unregister_cec:
>   i2c_unregister_device(adv7511->i2c_cec);
> - if (adv7511->cec_clk)
> - clk_disable_unprepare(adv7511->cec_clk);
> + clk_disable_unprepare(adv7511->cec_clk);
>  err_i2c_unregister_packet:
>   i2c_unregister_device(adv7511->i2c_packet);
>  err_i2c_unregister_edid:
> @@ -1311,8 +1310,7 @@ static int adv7511_remove(struct i2c_client *i2c)
>   if (adv7511->type == ADV7533 || adv7511->type == ADV7535)
>   adv7533_detach_dsi(adv7511);
>   i2c_unregister_device(adv7511->i2c_cec);
> - if (adv7511->cec_clk)
> - clk_disable_unprepare(adv7511->cec_clk);
> + clk_disable_unprepare(adv7511->cec_clk);
>  
>   adv7511_uninit_regulators(adv7511);
>  

-- 
Regards,

Laurent Pinchart


Re: [PATCH] drm: bridge: dw-hdmi: Remove redundant null check before clk_disable_unprepare

2020-12-20 Thread Laurent Pinchart
Hi Xu Wang,

Thank you for the patch.

On Fri, Nov 27, 2020 at 09:23:32AM +, Xu Wang wrote:
> Because clk_disable_unprepare() already checked NULL clock parameter,
> so the additional check is unnecessary, just remove them.
> 
> Signed-off-by: Xu Wang 

Reviewed-by: Laurent Pinchart 

> ---
>  drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 6 ++
>  1 file changed, 2 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c 
> b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> index 0c79a9ba48bb..dda4fa9a1a08 100644
> --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> @@ -3440,8 +3440,7 @@ struct dw_hdmi *dw_hdmi_probe(struct platform_device 
> *pdev,
>  
>  err_iahb:
>   clk_disable_unprepare(hdmi->iahb_clk);
> - if (hdmi->cec_clk)
> - clk_disable_unprepare(hdmi->cec_clk);
> + clk_disable_unprepare(hdmi->cec_clk);
>  err_isfr:
>   clk_disable_unprepare(hdmi->isfr_clk);
>  err_res:
> @@ -3465,8 +3464,7 @@ void dw_hdmi_remove(struct dw_hdmi *hdmi)
>  
>   clk_disable_unprepare(hdmi->iahb_clk);
>   clk_disable_unprepare(hdmi->isfr_clk);
> - if (hdmi->cec_clk)
> - clk_disable_unprepare(hdmi->cec_clk);
> + clk_disable_unprepare(hdmi->cec_clk);
>  
>   if (hdmi->i2c)
>   i2c_del_adapter(>i2c->adap);

-- 
Regards,

Laurent Pinchart


Re: [PATCH v4 9/9] media: uvcvideo: Implement UVC_QUIRK_PRIVACY_DURING_STREAM

2020-12-20 Thread Laurent Pinchart
quirks & UVC_QUIRK_PRIVACY_DURING_STREAM) {
if (!uvc_ext_gpio_is_streaming(dev))
return IRQ_HANDLED;
}

There's a potential race condition with VIDIOC_STREAMON and
VIDIOC_STREAMOFF. Could you explain what the device does exactly when
not streaming ? As the GPIO isn't tied to the UVC controller, how comes
the streaming state influences it ? Any hope the firmware could be fixed
instead ?

> +
> + uvc_privacy_gpio_event(dev);
> +
>   return IRQ_HANDLED;
>  }
>  
> +static const struct dmi_system_id privacy_valid_during_streamon[] = {
> + {
> + .ident = "HP Elite c1030 Chromebook",
> + .matches = {
> + DMI_MATCH(DMI_SYS_VENDOR, "HP"),
> + DMI_MATCH(DMI_PRODUCT_NAME, "Jinlon"),
> + },
> + },
> + {
> + .ident = "HP Pro c640 Chromebook",
> + .matches = {
> + DMI_MATCH(DMI_SYS_VENDOR, "HP"),
> + DMI_MATCH(DMI_PRODUCT_NAME, "Dratini"),
> + },
> + },
> + { } /* terminate list */
> +};
> +
> +
>  static int uvc_parse_gpio(struct uvc_device *dev)
>  {
>   struct uvc_entity *unit;
> @@ -1545,6 +1615,9 @@ static int uvc_parse_gpio(struct uvc_device *dev)
>   if (irq == -EPROBE_DEFER)
>   return -EPROBE_DEFER;
>  
> + if (dmi_check_system(privacy_valid_during_streamon))
> + dev->quirks |= UVC_QUIRK_PRIVACY_DURING_STREAM;
> +
>   if (irq < 0)
>   return 0;
>  
> diff --git a/drivers/media/usb/uvc/uvc_queue.c 
> b/drivers/media/usb/uvc/uvc_queue.c
> index cd60c6c1749e..e800d491303f 100644
> --- a/drivers/media/usb/uvc/uvc_queue.c
> +++ b/drivers/media/usb/uvc/uvc_queue.c
> @@ -337,9 +337,12 @@ int uvc_dequeue_buffer(struct uvc_video_queue *queue, 
> struct v4l2_buffer *buf,
>  int uvc_queue_streamon(struct uvc_video_queue *queue, enum v4l2_buf_type 
> type)
>  {
>   int ret;
> + struct uvc_streaming *stream = uvc_queue_to_stream(queue);
>  
>   mutex_lock(>mutex);
>   ret = vb2_streamon(>queue, type);
> + if (stream->dev->quirks & UVC_QUIRK_PRIVACY_DURING_STREAM)
> + uvc_privacy_gpio_event(stream->dev);
>   mutex_unlock(>mutex);
>  
>   return ret;
> diff --git a/drivers/media/usb/uvc/uvcvideo.h 
> b/drivers/media/usb/uvc/uvcvideo.h
> index 2b5ba4b02d3a..2a95b3ed3ea8 100644
> --- a/drivers/media/usb/uvc/uvcvideo.h
> +++ b/drivers/media/usb/uvc/uvcvideo.h
> @@ -6,6 +6,7 @@
>  #error "The uvcvideo.h header is deprecated, use linux/uvcvideo.h instead."
>  #endif /* __KERNEL__ */
>  
> +#include 
>  #include 
>  #include 
>  #include 
> @@ -209,6 +210,7 @@
>  #define UVC_QUIRK_RESTORE_CTRLS_ON_INIT  0x0400
>  #define UVC_QUIRK_FORCE_Y8   0x0800
>  #define UVC_QUIRK_FORCE_BPP  0x1000
> +#define UVC_QUIRK_PRIVACY_DURING_STREAM  0x2000
>  
>  /* Format flags */
>  #define UVC_FMT_FLAG_COMPRESSED  0x0001
> @@ -359,6 +361,7 @@ struct uvc_entity {
>   u8  bControlSize;
>   u8  *bmControls;
>   struct gpio_desc *gpio_privacy;
> + atomic_t  gpio_privacy_value;
>   } gpio;
>   };
>  
> @@ -815,6 +818,9 @@ extern const struct v4l2_file_operations uvc_fops;
>  int uvc_mc_register_entities(struct uvc_video_chain *chain);
>  void uvc_mc_cleanup_entity(struct uvc_entity *entity);
>  
> +/* Privacy gpio */
> +void uvc_privacy_gpio_event(struct uvc_device *dev);
> +
>  /* Video */
>  int uvc_video_init(struct uvc_streaming *stream);
>  int uvc_video_suspend(struct uvc_streaming *stream);

-- 
Regards,

Laurent Pinchart


Re: [PATCH v4 8/9] media: uvcvideo: New macro uvc_trace_cont

2020-12-20 Thread Laurent Pinchart
Hi Ricardo,

Thank you for the patch.

On Tue, Dec 15, 2020 at 04:44:38PM +0100, Ricardo Ribalda wrote:
> Remove all the duplicated code around pr_cont with a new macro.
> 
> Suggested-by: Joe Perches 
> Signed-off-by: Ricardo Ribalda 

Reviewed-by: Laurent Pinchart 

> ---
>  drivers/media/usb/uvc/uvc_driver.c | 57 +++---
>  drivers/media/usb/uvc/uvcvideo.h   |  6 
>  2 files changed, 27 insertions(+), 36 deletions(-)
> 
> diff --git a/drivers/media/usb/uvc/uvc_driver.c 
> b/drivers/media/usb/uvc/uvc_driver.c
> index 4379916a6ac1..e49491250e87 100644
> --- a/drivers/media/usb/uvc/uvc_driver.c
> +++ b/drivers/media/usb/uvc/uvc_driver.c
> @@ -1593,8 +1593,7 @@ static int uvc_scan_chain_entity(struct uvc_video_chain 
> *chain,
>  {
>   switch (UVC_ENTITY_TYPE(entity)) {
>   case UVC_VC_EXTENSION_UNIT:
> - if (uvc_trace_param & UVC_TRACE_PROBE)
> - pr_cont(" <- XU %d", entity->id);
> + uvc_trace_cont(UVC_TRACE_PROBE, " <- XU %d", entity->id);
>  
>   if (entity->bNrInPins != 1) {
>   uvc_trace(UVC_TRACE_DESCR, "Extension unit %d has more "
> @@ -1605,8 +1604,7 @@ static int uvc_scan_chain_entity(struct uvc_video_chain 
> *chain,
>   break;
>  
>   case UVC_VC_PROCESSING_UNIT:
> - if (uvc_trace_param & UVC_TRACE_PROBE)
> - pr_cont(" <- PU %d", entity->id);
> + uvc_trace_cont(UVC_TRACE_PROBE, " <- PU %d", entity->id);
>  
>   if (chain->processing != NULL) {
>   uvc_trace(UVC_TRACE_DESCR, "Found multiple "
> @@ -1618,8 +1616,7 @@ static int uvc_scan_chain_entity(struct uvc_video_chain 
> *chain,
>   break;
>  
>   case UVC_VC_SELECTOR_UNIT:
> - if (uvc_trace_param & UVC_TRACE_PROBE)
> - pr_cont(" <- SU %d", entity->id);
> + uvc_trace_cont(UVC_TRACE_PROBE, " <- SU %d", entity->id);
>  
>   /* Single-input selector units are ignored. */
>   if (entity->bNrInPins == 1)
> @@ -1637,27 +1634,22 @@ static int uvc_scan_chain_entity(struct 
> uvc_video_chain *chain,
>   case UVC_ITT_VENDOR_SPECIFIC:
>   case UVC_ITT_CAMERA:
>   case UVC_ITT_MEDIA_TRANSPORT_INPUT:
> - if (uvc_trace_param & UVC_TRACE_PROBE)
> - pr_cont(" <- IT %d\n", entity->id);
> + uvc_trace_cont(UVC_TRACE_PROBE, " <- IT %d\n", entity->id);
>  
>   break;
>  
>   case UVC_OTT_VENDOR_SPECIFIC:
>   case UVC_OTT_DISPLAY:
>   case UVC_OTT_MEDIA_TRANSPORT_OUTPUT:
> - if (uvc_trace_param & UVC_TRACE_PROBE)
> - pr_cont(" OT %d", entity->id);
> + uvc_trace_cont(UVC_TRACE_PROBE, " OT %d", entity->id);
>  
>   break;
>  
>   case UVC_TT_STREAMING:
> - if (UVC_ENTITY_IS_ITERM(entity)) {
> - if (uvc_trace_param & UVC_TRACE_PROBE)
> - pr_cont(" <- IT %d\n", entity->id);
> - } else {
> - if (uvc_trace_param & UVC_TRACE_PROBE)
> - pr_cont(" OT %d", entity->id);
> - }
> + if (UVC_ENTITY_IS_ITERM(entity))
> + uvc_trace_cont(UVC_TRACE_PROBE, " <- IT %d\n", 
> entity->id);
> + else
> + uvc_trace_cont(UVC_TRACE_PROBE, " OT %d", entity->id);
>  
>   break;
>  
> @@ -1704,13 +1696,11 @@ static int uvc_scan_chain_forward(struct 
> uvc_video_chain *chain,
>   }
>  
>   list_add_tail(>chain, >entities);
> - if (uvc_trace_param & UVC_TRACE_PROBE) {
> - if (!found)
> - pr_cont(" (->");
> + if (!found)
> + uvc_trace_cont(UVC_TRACE_PROBE, " (->");
>  
> - pr_cont(" XU %d", forward->id);
> - found = 1;
> - }
> + uvc_trace_cont(UVC_TRACE_PROBE, " XU %d", forward->id);
> + found = 1;
>   break;
>  
>   case UVC_OTT_VENDOR_SPECIFIC:
> @@ -1724,18 +1714,16 @@ static int uvc_scan_chain_forward(struct 

Re: [PATCH v4 7/9] media: uvcvideo: Use dev_ printk aliases

2020-12-20 Thread Laurent Pinchart
eed for curly braces.

>  }
>  
>  static void uvc_video_decode_data(struct uvc_urb *uvc_urb,
> @@ -1507,8 +1508,9 @@ static void uvc_video_complete(struct urb *urb)
>   break;
>  
>   default:
> - uvc_printk(KERN_WARNING, "Non-zero status (%d) in video "
> - "completion handler.\n", urb->status);
> + dev_warn(>intf->dev,
> +  "Non-zero status (%d) in video completion handler.\n",
> +  urb->status);
>   fallthrough;
>   case -ENOENT:   /* usb_poison_urb() called. */
>   if (stream->frozen)
> @@ -1545,9 +1547,8 @@ static void uvc_video_complete(struct urb *urb)
>   if (!uvc_urb->async_operations) {
>   ret = usb_submit_urb(uvc_urb->urb, GFP_ATOMIC);
>   if (ret < 0)
> - uvc_printk(KERN_ERR,
> -"Failed to resubmit video URB (%d).\n",
> -ret);
> + dev_err(>intf->dev,
> + "Failed to resubmit video URB (%d).\n", ret);
>   return;
>   }
>  
> @@ -1893,8 +1894,9 @@ static int uvc_video_start_transfer(struct 
> uvc_streaming *stream,
>   for_each_uvc_urb(uvc_urb, stream) {
>   ret = usb_submit_urb(uvc_urb->urb, gfp_flags);
>   if (ret < 0) {
> - uvc_printk(KERN_ERR, "Failed to submit URB %u (%d).\n",
> -uvc_urb_index(uvc_urb), ret);
> + dev_err(>intf->dev,
> + "Failed to submit URB %u (%d).\n",
> + uvc_urb_index(uvc_urb), ret);
>   uvc_video_stop_transfer(stream, 1);
>   return ret;
>   }
> @@ -1989,7 +1991,8 @@ int uvc_video_init(struct uvc_streaming *stream)
>   int ret;
>  
>   if (stream->nformats == 0) {
> - uvc_printk(KERN_INFO, "No supported video formats found.\n");
> + dev_info(>intf->dev,
> +      "No supported video formats found.\n");
>   return -EINVAL;
>   }
>  
> @@ -2029,8 +2032,8 @@ int uvc_video_init(struct uvc_streaming *stream)
>   }
>  
>   if (format->nframes == 0) {
> - uvc_printk(KERN_INFO, "No frame descriptor found for the "
> - "default format.\n");
> + dev_info(>intf->dev,
> +  "No frame descriptor found for the default format.\n");
>   return -EINVAL;
>   }
>  
> @@ -2064,8 +2067,8 @@ int uvc_video_init(struct uvc_streaming *stream)
>   if (stream->intf->num_altsetting == 1)
>   stream->decode = uvc_video_encode_bulk;
>   else {
> - uvc_printk(KERN_INFO, "Isochronous endpoints are not "
> - "supported for video output devices.\n");
> + dev_info(>intf->dev,
> +  "Isochronous endpoints are not supported for 
> video output devices.\n");
>   return -EINVAL;
>   }
>   }
> diff --git a/drivers/media/usb/uvc/uvcvideo.h 
> b/drivers/media/usb/uvc/uvcvideo.h
> index f87d14fb3f56..d8e2f27bf576 100644
> --- a/drivers/media/usb/uvc/uvcvideo.h
> +++ b/drivers/media/usb/uvc/uvcvideo.h
> @@ -742,20 +742,17 @@ extern unsigned int uvc_trace_param;
>  extern unsigned int uvc_timeout_param;
>  extern unsigned int uvc_hw_timestamps_param;
>  
> -#define uvc_trace(flag, msg...) \
> - do { \
> - if (uvc_trace_param & flag) \
> - printk(KERN_DEBUG "uvcvideo: " msg); \
> - } while (0)
> -
> -#define uvc_warn_once(dev, warn, msg...) \
> - do { \
> - if (!test_and_set_bit(warn, >warnings)) \
> - printk(KERN_INFO "uvcvideo: " msg); \
> - } while (0)
> -
> -#define uvc_printk(level, msg...) \
> - printk(level "uvcvideo: " msg)
> +#define uvc_trace(flag, fmt, ...)\
> +do { \
> + if (uvc_trace_param & flag) \
> + printk(KERN_DEBUG "uvcvideo: " fmt, ##__VA_ARGS__); \
> +} while (0)

It would be nice to use dev_printk(KERN_DEBUG, dev, ...) :-) (in a
separate patch).

> +
> +#define uvc_warn_once(_dev, warn, fmt, ...)  \
> +do { \
> + if (!test_and_set_bit(warn, &(_dev)->warnings)) \
> + dev_info(&(_dev)->udev->dev, fmt, ##__VA_ARGS__);   \
> +} while (0)

Could you please mention these changes in the commit message ?

Reviewed-by: Laurent Pinchart 

>  
>  /* --
>   * Internal functions.

-- 
Regards,

Laurent Pinchart


Re: [PATCH v4 6/9] media: uvcvideo: Add Privacy control based on EXT_GPIO

2020-12-20 Thread Laurent Pinchart
Hi Ricardo,

Thank you for the patch.

On Tue, Dec 15, 2020 at 04:44:36PM +0100, Ricardo Ribalda wrote:
> Add a new control and mapping for Privacy controls connected to
> UVC_GUID_EXT_GPIO_CONTROLLERs.
> 
> Signed-off-by: Ricardo Ribalda 

Reviewed-by: Laurent Pinchart 

> ---
>  drivers/media/usb/uvc/uvc_ctrl.c | 18 ++
>  1 file changed, 18 insertions(+)
> 
> diff --git a/drivers/media/usb/uvc/uvc_ctrl.c 
> b/drivers/media/usb/uvc/uvc_ctrl.c
> index 53da1d984883..511927e8b746 100644
> --- a/drivers/media/usb/uvc/uvc_ctrl.c
> +++ b/drivers/media/usb/uvc/uvc_ctrl.c
> @@ -347,6 +347,14 @@ static const struct uvc_control_info uvc_ctrls[] = {
>   | UVC_CTRL_FLAG_RESTORE
>   | UVC_CTRL_FLAG_AUTO_UPDATE,
>   },
> + {
> + .entity = UVC_GUID_EXT_GPIO_CONTROLLER,
> + .selector   = UVC_CT_PRIVACY_CONTROL,
> + .index  = 0,
> + .size   = 1,
> + .flags  = UVC_CTRL_FLAG_GET_CUR
> + | UVC_CTRL_FLAG_AUTO_UPDATE,
> + },
>  };
>  
>  static const struct uvc_menu_info power_line_frequency_controls[] = {
> @@ -735,6 +743,16 @@ static const struct uvc_control_mapping 
> uvc_ctrl_mappings[] = {
>   .v4l2_type  = V4L2_CTRL_TYPE_BOOLEAN,
>   .data_type  = UVC_CTRL_DATA_TYPE_BOOLEAN,
>   },
> + {
> + .id = V4L2_CID_PRIVACY,
> + .name   = "Privacy",
> + .entity = UVC_GUID_EXT_GPIO_CONTROLLER,
> + .selector   = UVC_CT_PRIVACY_CONTROL,
> + .size   = 1,
> + .offset = 0,
> + .v4l2_type  = V4L2_CTRL_TYPE_BOOLEAN,
> + .data_type  = UVC_CTRL_DATA_TYPE_BOOLEAN,
> + },
>  };
>  
>  /* 

-- 
Regards,

Laurent Pinchart


Re: [PATCH v4 2/9] media: uvcvideo: Allow external entities

2020-12-20 Thread Laurent Pinchart
Hi Ricardo,

Thank you for the patch.

On Tue, Dec 15, 2020 at 04:44:32PM +0100, Ricardo Ribalda wrote:
> Increase the size of the id, to avoid collisions with external entities.

Could you expand the commit message a bit to explain what external
entities are ?

> Signed-off-by: Ricardo Ribalda 
> ---
>  drivers/media/usb/uvc/uvc_driver.c | 2 +-
>  drivers/media/usb/uvc/uvcvideo.h   | 2 +-
>  2 files changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/media/usb/uvc/uvc_driver.c 
> b/drivers/media/usb/uvc/uvc_driver.c
> index 4cdd65d252d9..9f4451a2e0a6 100644
> --- a/drivers/media/usb/uvc/uvc_driver.c
> +++ b/drivers/media/usb/uvc/uvc_driver.c
> @@ -1024,7 +1024,7 @@ static const u8 uvc_media_transport_input_guid[16] =
>   UVC_GUID_UVC_MEDIA_TRANSPORT_INPUT;
>  static const u8 uvc_processing_guid[16] = UVC_GUID_UVC_PROCESSING;
>  
> -static struct uvc_entity *uvc_alloc_entity(u16 type, u8 id,
> +static struct uvc_entity *uvc_alloc_entity(u16 type, u16 id,
>   unsigned int num_pads, unsigned int extra_size)
>  {
>   struct uvc_entity *entity;
> diff --git a/drivers/media/usb/uvc/uvcvideo.h 
> b/drivers/media/usb/uvc/uvcvideo.h
> index df7bf2d104a3..00f985001c1d 100644
> --- a/drivers/media/usb/uvc/uvcvideo.h
> +++ b/drivers/media/usb/uvc/uvcvideo.h
> @@ -301,7 +301,7 @@ struct uvc_entity {
>* chain. */
>   unsigned int flags;
>  
> - u8 id;
> + u16 id; /* 0-255: usb entity. 256-65535: external entities */

How about

/*
 * Entities exposed by the UVC device use IDs 0-255, extra entities
 * implemented by the driver (such as the GPIO entity) use IDs 256 and
 * up.
 */

Reviewed-by: Laurent Pinchart 

>   u16 type;
>   char name[64];
>   u8 guid[16];

-- 
Regards,

Laurent Pinchart


Re: [PATCH v4 5/9] media: uvcvideo: Implement UVC_EXT_GPIO_UNIT

2020-12-20 Thread Laurent Pinchart
, or moving IRQ registration to a separate function, called later
during the initialization. I think I have a preference for the latter.

> +
> + return 0;
> +}
> +
>  /* 
>   * UVC device scan
>   */
> @@ -1917,6 +2009,7 @@ static int uvc_scan_device(struct uvc_device *dev)
>  {
>   struct uvc_video_chain *chain;
>   struct uvc_entity *term;
> + struct uvc_entity *unit;
>  
>   list_for_each_entry(term, >entities, list) {
>   if (!UVC_ENTITY_IS_OTERM(term))
> @@ -1955,6 +2048,13 @@ static int uvc_scan_device(struct uvc_device *dev)
>   return -1;
>   }
>  
> + /* Add GPIO entities to the first chain */

s/chain/chain./

> + chain = list_first_entry(>chains, struct uvc_video_chain, list);
> + list_for_each_entry(unit, >entities, list) {
> + if (UVC_ENTITY_TYPE(unit) == UVC_EXT_GPIO_UNIT)
> + list_add_tail(>chain, >entities);
> + }
> +
>   return 0;
>  }
>  
> @@ -2287,6 +2387,12 @@ static int uvc_probe(struct usb_interface *intf,
>   goto error;
>   }
>  
> + /* Parse the associated GPIOs */

s/GPIOs/GPIOs./

> + if (uvc_parse_gpio(dev) < 0) {
> + uvc_trace(UVC_TRACE_PROBE, "Unable to parse UVC GPIOs\n");
> + goto error;
> + }
> +
>   uvc_printk(KERN_INFO, "Found UVC %u.%02x device %s (%04x:%04x)\n",
>   dev->uvc_version >> 8, dev->uvc_version & 0xff,
>   udev->product ? udev->product : "",
> diff --git a/drivers/media/usb/uvc/uvcvideo.h 
> b/drivers/media/usb/uvc/uvcvideo.h
> index ae464ba83f4f..f87d14fb3f56 100644
> --- a/drivers/media/usb/uvc/uvcvideo.h
> +++ b/drivers/media/usb/uvc/uvcvideo.h
> @@ -6,6 +6,7 @@
>  #error "The uvcvideo.h header is deprecated, use linux/uvcvideo.h instead."
>  #endif /* __KERNEL__ */
>  
> +#include 

We can use a forward declaration of struct gpio_desc in this file.

>  #include 
>  #include 
>  #include 
> @@ -37,6 +38,8 @@
>   (UVC_ENTITY_IS_TERM(entity) && \
>   ((entity)->type & 0x8000) == UVC_TERM_OUTPUT)
>  
> +#define UVC_EXT_GPIO_UNIT 0x7ffe
> +#define UVC_EXT_GPIO_UNIT_ID 0x100

Maybe a couple of tabs to align this with the other defines above ?

>  
>  /* 
>   * GUIDs
> @@ -56,6 +59,9 @@
>  #define UVC_GUID_UVC_SELECTOR \
>   {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
>0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02}
> +#define UVC_GUID_EXT_GPIO_CONTROLLER \
> + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
> +  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x03}
>  
>  #define UVC_GUID_FORMAT_MJPEG \
>   { 'M',  'J',  'P',  'G', 0x00, 0x00, 0x10, 0x00, \
> @@ -348,6 +354,12 @@ struct uvc_entity {
>   u8  *bmControls;
>   u8  *bmControlsType;
>   } extension;
> +
> + struct {
> + u8  bControlSize;
> + u8  *bmControls;
> + struct gpio_desc *gpio_privacy;
> + } gpio;
>   };
>  
>   u8 bNrInPins;

-- 
Regards,

Laurent Pinchart


Re: [PATCH v4 4/9] media: uvcvideo: Entity defined get_info and get_cur

2020-12-20 Thread Laurent Pinchart
Hi Ricardo,

Thank you for the patch.

Maybe s/Entity defined/Allow entity-defined/ in the subject line ?

On Tue, Dec 15, 2020 at 04:44:34PM +0100, Ricardo Ribalda wrote:
> Allows controls to get their properties and current value
> from an entity-defined function instead of via a query to the USB
> device.
> 
> Signed-off-by: Ricardo Ribalda 
> ---
>  drivers/media/usb/uvc/uvc_ctrl.c | 22 ++
>  drivers/media/usb/uvc/uvcvideo.h |  5 +
>  2 files changed, 23 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/media/usb/uvc/uvc_ctrl.c 
> b/drivers/media/usb/uvc/uvc_ctrl.c
> index 9f6174a10e73..531816762892 100644
> --- a/drivers/media/usb/uvc/uvc_ctrl.c
> +++ b/drivers/media/usb/uvc/uvc_ctrl.c
> @@ -980,10 +980,20 @@ static int __uvc_ctrl_get(struct uvc_video_chain *chain,
>   return -EACCES;
>  
>   if (!ctrl->loaded) {
> - ret = uvc_query_ctrl(chain->dev, UVC_GET_CUR, ctrl->entity->id,
> - chain->dev->intfnum, ctrl->info.selector,
> + if (ctrl->entity->get_cur) {
> + ret = ctrl->entity->get_cur(chain->dev,
> + ctrl->entity,
> + ctrl->info.selector,
>   uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT),
>   ctrl->info.size);
> + } else {
> + ret = uvc_query_ctrl(chain->dev, UVC_GET_CUR,
> + ctrl->entity->id,
> + chain->dev->intfnum,
> + ctrl->info.selector,
> + uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT),
> + ctrl->info.size);

We could possibly set entity->get_cur by default to a function wrapping
uvc_query_ctrl() to avoid the condition here. This isn't mandatory for
now though, but I'll toy with it on top of the series to avoid storing
function pointers in a non-const structure.

Reviewed-by: Laurent Pinchart 

> + }
>   if (ret < 0)
>   return ret;
>  
> @@ -1687,8 +1697,12 @@ static int uvc_ctrl_get_flags(struct uvc_device *dev,
>   if (data == NULL)
>   return -ENOMEM;
>  
> - ret = uvc_query_ctrl(dev, UVC_GET_INFO, ctrl->entity->id, dev->intfnum,
> -  info->selector, data, 1);
> + if (ctrl->entity->get_info)
> + ret = ctrl->entity->get_info(dev, ctrl->entity,
> +  ctrl->info.selector, data);
> + else
> + ret = uvc_query_ctrl(dev, UVC_GET_INFO, ctrl->entity->id,
> +  dev->intfnum, info->selector, data, 1);
>   if (!ret)
>   info->flags |= (data[0] & UVC_CONTROL_CAP_GET ?
>   UVC_CTRL_FLAG_GET_CUR : 0)
> diff --git a/drivers/media/usb/uvc/uvcvideo.h 
> b/drivers/media/usb/uvc/uvcvideo.h
> index 00f985001c1d..ae464ba83f4f 100644
> --- a/drivers/media/usb/uvc/uvcvideo.h
> +++ b/drivers/media/usb/uvc/uvcvideo.h
> @@ -353,6 +353,11 @@ struct uvc_entity {
>   u8 bNrInPins;
>   u8 *baSourceID;
>  
> + int (*get_info)(struct uvc_device *dev, struct uvc_entity *entity,
> + u8 cs, u8 *caps);
> + int (*get_cur)(struct uvc_device *dev, struct uvc_entity *entity,
> +u8 cs, void *data, u16 size);
> +
>   unsigned int ncontrols;
>   struct uvc_control *controls;
>  };

-- 
Regards,

Laurent Pinchart


Re: [PATCH v4 3/9] media: uvcvideo: Allow entities with no pads

2020-12-20 Thread Laurent Pinchart
Hi Ricardo,

Thank you for the patch.

On Tue, Dec 15, 2020 at 04:44:33PM +0100, Ricardo Ribalda wrote:
> Avoid an underflow while calculating the number of inputs for entities
> with zero pads.
> 
> Signed-off-by: Ricardo Ribalda 
> ---
>  drivers/media/usb/uvc/uvc_driver.c | 8 ++--
>  1 file changed, 6 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/media/usb/uvc/uvc_driver.c 
> b/drivers/media/usb/uvc/uvc_driver.c
> index 9f4451a2e0a6..534629ecd60d 100644
> --- a/drivers/media/usb/uvc/uvc_driver.c
> +++ b/drivers/media/usb/uvc/uvc_driver.c
> @@ -1033,7 +1033,11 @@ static struct uvc_entity *uvc_alloc_entity(u16 type, 
> u16 id,
>   unsigned int i;
>  
>   extra_size = roundup(extra_size, sizeof(*entity->pads));
> - num_inputs = (type & UVC_TERM_OUTPUT) ? num_pads : num_pads - 1;
> + if (num_pads)
> + num_inputs = (type & UVC_TERM_OUTPUT) ? num_pads :
> + num_pads - 1;

This is a weird indentation. How about the following ?

num_inputs = type & UVC_TERM_OUTPUT ? num_pads : num_pads - 1;

I can fix this when applying.

Reviewed-by: Laurent Pinchart 

> + else
> + num_inputs = 0;
>   size = sizeof(*entity) + extra_size + sizeof(*entity->pads) * num_pads
>+ num_inputs;
>   entity = kzalloc(size, GFP_KERNEL);
> @@ -1066,7 +1070,7 @@ static struct uvc_entity *uvc_alloc_entity(u16 type, 
> u16 id,
>  
>   for (i = 0; i < num_inputs; ++i)
>   entity->pads[i].flags = MEDIA_PAD_FL_SINK;
> - if (!UVC_ENTITY_IS_OTERM(entity))
> + if (!UVC_ENTITY_IS_OTERM(entity) && num_pads)
>   entity->pads[num_pads-1].flags = MEDIA_PAD_FL_SOURCE;
>  
>   entity->bNrInPins = num_inputs;

-- 
Regards,

Laurent Pinchart


Re: [PATCH v4 1/9] media: uvcvideo: Move guid to entity

2020-12-20 Thread Laurent Pinchart
Hi Ricardo,

Thank you for the patch.

On Tue, Dec 15, 2020 at 04:44:31PM +0100, Ricardo Ribalda wrote:
> Instead of having multiple copies of the entity guid on the code, move
> it to the entity structure.
> 
> Reviewed-by: Laurent Pinchart 
> Signed-off-by: Ricardo Ribalda 
> ---
>  drivers/media/usb/uvc/uvc_ctrl.c   | 30 --
>  drivers/media/usb/uvc/uvc_driver.c | 26 --
>  drivers/media/usb/uvc/uvcvideo.h   |  2 +-
>  3 files changed, 29 insertions(+), 29 deletions(-)
> 
> diff --git a/drivers/media/usb/uvc/uvc_ctrl.c 
> b/drivers/media/usb/uvc/uvc_ctrl.c
> index 011e69427b7c..9f6174a10e73 100644
> --- a/drivers/media/usb/uvc/uvc_ctrl.c
> +++ b/drivers/media/usb/uvc/uvc_ctrl.c
> @@ -826,31 +826,10 @@ static void uvc_set_le_value(struct uvc_control_mapping 
> *mapping,
>   * Terminal and unit management
>   */
>  
> -static const u8 uvc_processing_guid[16] = UVC_GUID_UVC_PROCESSING;
> -static const u8 uvc_camera_guid[16] = UVC_GUID_UVC_CAMERA;
> -static const u8 uvc_media_transport_input_guid[16] =
> - UVC_GUID_UVC_MEDIA_TRANSPORT_INPUT;
> -
>  static int uvc_entity_match_guid(const struct uvc_entity *entity,
> - const u8 guid[16])
> +  const u8 guid[16])
>  {
> - switch (UVC_ENTITY_TYPE(entity)) {
> - case UVC_ITT_CAMERA:
> - return memcmp(uvc_camera_guid, guid, 16) == 0;
> -
> - case UVC_ITT_MEDIA_TRANSPORT_INPUT:
> - return memcmp(uvc_media_transport_input_guid, guid, 16) == 0;
> -
> - case UVC_VC_PROCESSING_UNIT:
> - return memcmp(uvc_processing_guid, guid, 16) == 0;
> -
> - case UVC_VC_EXTENSION_UNIT:
> - return memcmp(entity->extension.guidExtensionCode,
> -   guid, 16) == 0;
> -
> - default:
> - return 0;
> - }
> + return memcmp(entity->guid, guid, sizeof(entity->guid)) == 0;
>  }
>  
>  /* 
> @@ -1776,8 +1755,7 @@ static int uvc_ctrl_fill_xu_info(struct uvc_device *dev,
>   if (data == NULL)
>   return -ENOMEM;
>  
> - memcpy(info->entity, ctrl->entity->extension.guidExtensionCode,
> -sizeof(info->entity));
> + memcpy(info->entity, ctrl->entity->guid, sizeof(info->entity));
>   info->index = ctrl->index;
>   info->selector = ctrl->index + 1;
>  
> @@ -1883,7 +1861,7 @@ int uvc_xu_ctrl_query(struct uvc_video_chain *chain,
>  
>   if (!found) {
>   uvc_trace(UVC_TRACE_CONTROL, "Control %pUl/%u not found.\n",
> - entity->extension.guidExtensionCode, xqry->selector);
> + entity->guid, xqry->selector);
>   return -ENOENT;
>   }
>  
> diff --git a/drivers/media/usb/uvc/uvc_driver.c 
> b/drivers/media/usb/uvc/uvc_driver.c
> index ddb9eaa11be7..4cdd65d252d9 100644
> --- a/drivers/media/usb/uvc/uvc_driver.c
> +++ b/drivers/media/usb/uvc/uvc_driver.c
> @@ -1019,6 +1019,11 @@ static int uvc_parse_streaming(struct uvc_device *dev,
>   return ret;
>  }
>  
> +static const u8 uvc_camera_guid[16] = UVC_GUID_UVC_CAMERA;
> +static const u8 uvc_media_transport_input_guid[16] =
> + UVC_GUID_UVC_MEDIA_TRANSPORT_INPUT;
> +static const u8 uvc_processing_guid[16] = UVC_GUID_UVC_PROCESSING;
> +
>  static struct uvc_entity *uvc_alloc_entity(u16 type, u8 id,
>   unsigned int num_pads, unsigned int extra_size)
>  {
> @@ -1038,6 +1043,23 @@ static struct uvc_entity *uvc_alloc_entity(u16 type, 
> u8 id,
>   entity->id = id;
>   entity->type = type;
>  
> +

Nearly there, just one blank line to remove :-) I'll fix this when
applying.

> + /*
> +  * Set the GUID for standard entity types. For extension units, the GUID
> +  * is initialized by the caller.
> +  */
> + switch (type) {
> + case UVC_ITT_CAMERA:
> + memcpy(entity->guid, uvc_camera_guid, 16);
> + break;
> + case UVC_ITT_MEDIA_TRANSPORT_INPUT:
> + memcpy(entity->guid, uvc_media_transport_input_guid, 16);
> + break;
> + case UVC_VC_PROCESSING_UNIT:
> + memcpy(entity->guid, uvc_processing_guid, 16);
> + break;
> + }
> +
>   entity->num_links = 0;
>   entity->num_pads = num_pads;
>   entity->pads = ((void *)(entity + 1)) + extra_size;
> @@ -1109,7 +1131,7 @@ static int uvc_parse_vendor_control(struct uvc_device 
> *dev,
>   if (unit == NULL)
>   return -ENOMEM;
>  
>

Re: [PATCH 1/1] v4l: ioctl: Fix memory leak in video_usercopy

2020-12-20 Thread Laurent Pinchart
Hi Sakari,

Thank you for the patch.

On Sun, Dec 20, 2020 at 01:06:51PM +0200, Sakari Ailus wrote:
> When an IOCTL with argument size larger than 128 that also used array
> arguments were handled, two memory allocations were made but alas, only
> the latter one of them was released.

Alas, this fills my heart with sorrow indeed :-)

> This happened because there was only
> a single local variable to hold such a temporary allocation.
> 
> Fix this by adding separate variables to hold the pointers to the
> temporary allocations.
> 
> Reported-by: Arnd Bergmann 
> Reported-by: syzbot+1115e79c8df6472c6...@syzkaller.appspotmail.com
> Fixes: d14e6d76ebf7 ("[media] v4l: Add multi-planar ioctl handling code")
> Cc: sta...@vger.kernel.org
> Signed-off-by: Sakari Ailus 
> ---
>  drivers/media/v4l2-core/v4l2-ioctl.c | 31 +---
>  1 file changed, 14 insertions(+), 17 deletions(-)
> 
> diff --git a/drivers/media/v4l2-core/v4l2-ioctl.c 
> b/drivers/media/v4l2-core/v4l2-ioctl.c
> index 3198abdd538ce..f42a779948779 100644
> --- a/drivers/media/v4l2-core/v4l2-ioctl.c
> +++ b/drivers/media/v4l2-core/v4l2-ioctl.c
> @@ -3283,7 +3283,7 @@ video_usercopy(struct file *file, unsigned int 
> orig_cmd, unsigned long arg,
>  v4l2_kioctl func)
>  {
>   charsbuf[128];
> - void*mbuf = NULL;
> + void*mbuf = NULL, *array_buf = NULL;
>   void*parg = (void *)arg;
>   longerr  = -EINVAL;
>   boolhas_array_args;
> @@ -3318,27 +3318,21 @@ video_usercopy(struct file *file, unsigned int 
> orig_cmd, unsigned long arg,
>   has_array_args = err;
>  
>   if (has_array_args) {
> - /*
> -  * When adding new types of array args, make sure that the
> -  * parent argument to ioctl (which contains the pointer to the
> -  * array) fits into sbuf (so that mbuf will still remain
> -  * unused up to here).
> -  */
> - mbuf = kvmalloc(array_size, GFP_KERNEL);
> + array_buf = kvmalloc(array_size, GFP_KERNEL);
>   err = -ENOMEM;
> - if (NULL == mbuf)
> + if (array_buf == NULL)
>   goto out_array_args;
>   err = -EFAULT;
>   if (in_compat_syscall())
> - err = v4l2_compat_get_array_args(file, mbuf, user_ptr,
> -  array_size, orig_cmd,
> -  parg);
> + err = v4l2_compat_get_array_args(file, array_buf,
> +  user_ptr, array_size,
> +  orig_cmd, parg);
>   else
> - err = copy_from_user(mbuf, user_ptr, array_size) ?
> + err = copy_from_user(array_buf, user_ptr, array_size) ?
>   -EFAULT : 0;
>   if (err)
>   goto out_array_args;
> - *kernel_ptr = mbuf;
> + *kernel_ptr = array_buf;
>   }
>  
>   /* Handles IOCTL */
> @@ -3360,12 +3354,14 @@ video_usercopy(struct file *file, unsigned int 
> orig_cmd, unsigned long arg,
>   if (in_compat_syscall()) {
>   int put_err;
>  
> - put_err = v4l2_compat_put_array_args(file, user_ptr, 
> mbuf,
> -  array_size, 
> orig_cmd,
> + put_err = v4l2_compat_put_array_args(file, user_ptr,
> +  array_buf,
> +      array_size,
> +  orig_cmd,
>parg);

orig_cmd and pargs would fit on the same line if you want to.

Reviewed-by: Laurent Pinchart 

>   if (put_err)
>   err = put_err;
> - } else if (copy_to_user(user_ptr, mbuf, array_size)) {
> + } else if (copy_to_user(user_ptr, array_buf, array_size)) {
>   err = -EFAULT;
>   }
>   goto out_array_args;
> @@ -3381,6 +3377,7 @@ video_usercopy(struct file *file, unsigned int 
> orig_cmd, unsigned long arg,
>   if (video_put_user((void __user *)arg, parg, cmd, orig_cmd))
>   err = -EFAULT;
>  out:
> + kvfree(array_buf);
>   kvfree(mbuf);
>   return err;
>  }

-- 
Regards,

Laurent Pinchart


Re: [PATCH v3 1/2] media: dt-bindings: Convert video-interfaces.txt properties to schemas

2020-12-19 Thread Laurent Pinchart
Hi Rob,

On Fri, Dec 18, 2020 at 12:19:55PM -0600, Rob Herring wrote:
> On Wed, Dec 16, 2020 at 04:52:20PM +0200, Laurent Pinchart wrote:
> > On Thu, Dec 10, 2020 at 03:16:24PM -0600, Rob Herring wrote:
> > > Convert video-interfaces.txt to DT schema. As it contains a mixture of
> > > device level and endpoint properties, split it up into 2 schemas.
> > > 
> > > Binding schemas will need to reference both the graph.yaml and
> > > video-interfaces.yaml schemas. The exact schema depends on how many
> > > ports and endpoints for the binding. A single port with a single
> > > endpoint looks similar to this:
> > > 
> > >   port:
> > > $ref: /schemas/graph.yaml#/$defs/port-base
> > > 
> > > properties:
> > >   endpoint:
> > > $ref: video-interfaces.yaml#
> > > unevaluatedProperties: false
> > > 
> > > properties:
> > >   bus-width:
> > > enum: [ 8, 10, 12, 16 ]
> > > 
> > >   pclk-sample: true
> > >   hsync-active: true
> > >   vsync-active: true
> > > 
> > > required:
> > >   - bus-width
> > > 
> > > additionalProperties: false
> > > 
> > > Cc: Guennadi Liakhovetski 
> > > Acked-by: Sakari Ailus 
> > > Acked-by: Jacopo Mondi 
> > > Signed-off-by: Rob Herring 
> > > ---
> > > I need acks for dual licensing from the listed maintainers.
> > > 
> > > v3:
> > > - Support up to 9 physical lanes
> > > - Set lane-polarities array bounds
> > > ---
> > >  .../media/video-interface-devices.yaml| 406 +++
> > >  .../bindings/media/video-interfaces.txt   | 640 +-
> > >  .../bindings/media/video-interfaces.yaml  | 346 ++
> > >  3 files changed, 753 insertions(+), 639 deletions(-)
> > >  create mode 100644 
> > > Documentation/devicetree/bindings/media/video-interface-devices.yaml
> > >  create mode 100644 
> > > Documentation/devicetree/bindings/media/video-interfaces.yaml
> 
> 
> > > diff --git 
> > > a/Documentation/devicetree/bindings/media/video-interfaces.yaml 
> > > b/Documentation/devicetree/bindings/media/video-interfaces.yaml
> > > new file mode 100644
> > > index ..fefca7d98718
> > > --- /dev/null
> > > +++ b/Documentation/devicetree/bindings/media/video-interfaces.yaml
> > > @@ -0,0 +1,346 @@
> > > +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> > > +%YAML 1.2
> > > +---
> > > +$id: http://devicetree.org/schemas/media/video-interfaces.yaml#
> > > +$schema: http://devicetree.org/meta-schemas/core.yaml#
> > > +
> > > +title: Common bindings for video receiver and transmitter interface 
> > > endpoints
> > > +
> > > +maintainers:
> > > +  - Guennadi Liakhovetski 
> > > +  - Sakari Ailus 
> > > +
> > > +description: |
> > > +  Video data pipelines usually consist of external devices, e.g. camera 
> > > sensors,
> > > +  controlled over an I2C, SPI or UART bus, and SoC internal IP blocks, 
> > > including
> > > +  video DMA engines and video data processors.
> > > +
> > > +  SoC internal blocks are described by DT nodes, placed similarly to 
> > > other SoC
> > > +  blocks.  External devices are represented as child nodes of their 
> > > respective
> > > +  bus controller nodes, e.g. I2C.
> > > +
> > > +  Data interfaces on all video devices are described by their child 
> > > 'port' nodes.
> > > +  Configuration of a port depends on other devices participating in the 
> > > data
> > > +  transfer and is described by 'endpoint' subnodes.
> > > +
> > > +  device {
> > > +  ...
> > > +  ports {
> > > +  #address-cells = <1>;
> > > +  #size-cells = <0>;
> > > +
> > > +  port@0 {
> > > +  ...
> > > +  endpoint@0 { ... };
> > > +  endpoint@1 { ... };
> > > +  };
> > > +  port@1 { ... };
> > > +  };
> > > +  };
> > > +
> > > +  If a port can be configured to work with more than one remote device 
> > > on the same
> > > +  bus, an 'endpoint' child node must be provided for each of them.  If 
>

Re: [PATCH v2 12/12] ipu3-cio2: Add cio2-bridge to ipu3-cio2 driver

2020-12-18 Thread Laurent Pinchart
Hi Daniel,

On Fri, Dec 18, 2020 at 11:57:54PM +, Daniel Scally wrote:
> Hi Laurent - thanks for the comments
> 
> On 18/12/2020 16:53, Laurent Pinchart wrote:
> >> +static void cio2_bridge_init_property_names(struct cio2_sensor *sensor)
> >> +{
> >> +  strscpy(sensor->prop_names.clock_frequency, "clock-frequency",
> >> +  sizeof(sensor->prop_names.clock_frequency));
> >> +  strscpy(sensor->prop_names.rotation, "rotation",
> >> +  sizeof(sensor->prop_names.rotation));
> >> +  strscpy(sensor->prop_names.bus_type, "bus-type",
> >> +  sizeof(sensor->prop_names.bus_type));
> >> +  strscpy(sensor->prop_names.data_lanes, "data-lanes",
> >> +  sizeof(sensor->prop_names.data_lanes));
> >> +  strscpy(sensor->prop_names.remote_endpoint, "remote-endpoint",
> >> +  sizeof(sensor->prop_names.remote_endpoint));
> >> +  strscpy(sensor->prop_names.link_frequencies, "link-frequencies",
> >> +  sizeof(sensor->prop_names.link_frequencies));
> > 
> > Just curious, was there anything not working correctly with the proposal
> > I made ?
> > 
> > static const struct cio2_property_names prop_names = {
> > .clock_frequency = "clock-frequency",
> > .rotation = "rotation",
> > .bus_type = "bus-type",
> > .data_lanes = "data-lanes",
> > .remote_endpoint = "remote-endpoint",
> > };
> > 
> > static void cio2_bridge_init_property_names(struct cio2_sensor *sensor)
> > {
> > sensor->prop_names = prop_names;
> > }
> > 
> > It generates a warning when the string is too long for the field size,
> > which should help catching issues at compilation time.
> 
> Yes, though I don't know how much of a real-world problem it would have
> been - if you recall we have the issue that the device grabs a reference
> to the software_nodes (after we stopped delaying until after the
> i2c_client is available), which means we can't safely free the
> cio2_bridge struct on module unload. That also means we can't rely on
> those pointers to string literals existing, because if the ipu3-cio2
> module gets unloaded they'll be gone.

But the strings above are not stored as literals in .rodata, they're
copied in prop_names (itself in .rodata), which is then copied to
sensor->prop_names.

> Shame, as it's way neater.
> 
> >> +static void cio2_bridge_init_swnode_names(struct cio2_sensor *sensor)
> >> +{
> >> +  snprintf(sensor->node_names.remote_port, 7, "port@%u", 
> >> sensor->ssdb.link);
> >> +  strscpy(sensor->node_names.port, "port@0", 
> >> sizeof(sensor->node_names.port));
> >> +  strscpy(sensor->node_names.endpoint, "endpoint@0", 
> >> sizeof(sensor->node_names.endpoint));
> > 
> > I'd wrap lines, but maybe that's because I'm an old-school, 80-columns
> > programmer :-)
> 
> Heh sure, I'll wrap them.
> 
> >> +static int cio2_bridge_connect_sensors(struct cio2_bridge *bridge,
> >> + struct pci_dev *cio2)
> >> +{
> >> +  struct fwnode_handle *fwnode;
> >> +  struct cio2_sensor *sensor;
> >> +  struct acpi_device *adev;
> >> +  unsigned int i;
> >> +  int ret = 0;
> >> +
> >> +  for (i = 0; i < ARRAY_SIZE(cio2_supported_sensors); i++) {
> >> +  const struct cio2_sensor_config *cfg = 
> >> _supported_sensors[i];
> >> +
> >> +  for_each_acpi_dev_match(adev, cfg->hid, NULL, -1) {
> >> +  if (bridge->n_sensors >= CIO2_NUM_PORTS) {
> >> +  dev_warn(>dev, "Exceeded available CIO2 
> >> ports\n");
> >> +  /* overflow i so outer loop ceases */
> >> +  i = ARRAY_SIZE(cio2_supported_sensors);
> >> +  break;
> > 
> > Or just
> > 
> > return 0;
> > 
> > ?
> 
> Derp, yes of course.
> 
> 
> >> +/* Data representation as it is in ACPI SSDB buffer */
> >> +struct cio2_sensor_ssdb {
> >> +  u8 version; /*  */
> >> +  u8 sku; /* 0001 */
> >> +  u8 guid_csi2[16];   /* 0002 */
> >> +  u8 devfunction; /* 0003 */
> >> +  u8 bus;  

Re: [PATCH v2 12/12] ipu3-cio2: Add cio2-bridge to ipu3-cio2 driver

2020-12-18 Thread Laurent Pinchart
  goto err_put_adev;
> +
> + fwnode = 
> software_node_fwnode(>swnodes[SWNODE_SENSOR_HID]);
> + if (!fwnode) {
> + ret = -ENODEV;
> + goto err_free_swnodes;
> + }
> +
> + adev->fwnode.secondary = fwnode;
> +
> + dev_info(>dev, "Found supported sensor %s\n",
> +  acpi_dev_name(adev));
> +
> + bridge->n_sensors++;
> + }
> + }
> +
> + return ret;
> +
> +err_free_swnodes:
> + software_node_unregister_nodes(sensor->swnodes);
> +err_put_adev:
> + acpi_dev_put(sensor->adev);
> +
> + return ret;
> +}
> +
> +int cio2_bridge_init(struct pci_dev *cio2)
> +{
> + struct device *dev = >dev;
> + struct fwnode_handle *fwnode;
> + struct cio2_bridge *bridge;
> + int ret;
> +
> + bridge = kzalloc(sizeof(*bridge), GFP_KERNEL);
> + if (!bridge)
> + return -ENOMEM;
> +
> + strscpy(bridge->cio2_node_name, CIO2_HID, 
> sizeof(bridge->cio2_node_name));
> + bridge->cio2_hid_node.name = bridge->cio2_node_name;
> +
> + ret = software_node_register(>cio2_hid_node);
> + if (ret < 0) {
> + dev_err(dev, "Failed to register the CIO2 HID node\n");
> + goto err_free_bridge;
> + }
> +
> + ret = cio2_bridge_connect_sensors(bridge, cio2);
> + if (ret || bridge->n_sensors == 0)
> + goto err_unregister_cio2;
> +
> + dev_info(dev, "Connected %d cameras\n", bridge->n_sensors);
> +
> + fwnode = software_node_fwnode(>cio2_hid_node);
> + if (!fwnode) {
> + dev_err(dev, "Error getting fwnode from cio2 software_node\n");
> + ret = -ENODEV;
> + goto err_unregister_sensors;
> + }
> +
> + set_secondary_fwnode(dev, fwnode);
> +
> + return 0;
> +
> +err_unregister_sensors:
> + cio2_bridge_unregister_sensors(bridge);
> +err_unregister_cio2:
> + software_node_unregister(>cio2_hid_node);
> +err_free_bridge:
> + kfree(bridge);
> +
> + return ret;
> +}
> diff --git a/drivers/media/pci/intel/ipu3/cio2-bridge.h 
> b/drivers/media/pci/intel/ipu3/cio2-bridge.h
> new file mode 100644
> index ..f89a8e33f82c
> --- /dev/null
> +++ b/drivers/media/pci/intel/ipu3/cio2-bridge.h
> @@ -0,0 +1,122 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +/* Author: Dan Scally  */
> +#ifndef __CIO2_BRIDGE_H
> +#define __CIO2_BRIDGE_H
> +
> +#include 
> +
> +#define CIO2_HID "INT343E"
> +#define CIO2_NUM_PORTS   4
> +#define MAX_NUM_LINK_FREQS   3
> +
> +#define CIO2_SENSOR_CONFIG(_HID, _NR, ...)   \
> + {   \
> + .hid = _HID,\
> + .nr_link_freqs = _NR,   \
> + .link_freqs = { __VA_ARGS__ }   \
> + }
> +
> +#define NODE_SENSOR(_HID, _PROPS)\
> + ((const struct software_node) { \
> + .name = _HID,   \
> + .properties = _PROPS,   \
> + })
> +
> +#define NODE_PORT(_PORT, _SENSOR_NODE)   \
> + ((const struct software_node) { \
> + _PORT,  \
> + _SENSOR_NODE,   \
> + })
> +
> +#define NODE_ENDPOINT(_EP, _PORT, _PROPS)\
> + ((const struct software_node) { \
> + _EP,\
> + _PORT,  \
> + _PROPS, \
> + })
> +
> +enum cio2_sensor_swnodes {
> + SWNODE_SENSOR_HID,
> + SWNODE_SENSOR_PORT,
> + SWNODE_SENSOR_ENDPOINT,
> + SWNODE_CIO2_PORT,
> + SWNODE_CIO2_ENDPOINT,
> + NR_OF_SENSOR_SWNODES
> +};
> +
> +/* Data representation as it is in ACPI SSDB buffer */
> +struct cio2_sensor_ssdb {
> + u8 version; /*  */
> + u8 sku; /* 0001 */
> + u8 guid_csi2[16];   /* 0002 */
> + u8 devfunction; /* 0003 */
> + u8 bus; /* 0004 */
> + u32 dphylinkenfuses;/* 0005 */
> + u32 clockdiv;   /* 0009 */
> + u8 link;/* 0013 */
> + u8 lanes;

Re: [PATCH v2 06/12] software_node: Add support for fwnode_graph*() family of functions

2020-12-18 Thread Laurent Pinchart
+ return NULL;
> +
> + ref = prop->pointer;
> +
> + return software_node_get(software_node_fwnode(ref[0].node));
> +}
> +
> +static struct fwnode_handle *
> +software_node_graph_get_port_parent(struct fwnode_handle *fwnode)
> +{
> + struct swnode *swnode = to_swnode(fwnode);
> + struct fwnode_handle *parent;
> +
> + if (!strcmp(swnode->parent->node->name, "ports"))
> + parent = >parent->parent->fwnode;
> + else
> + parent = >parent->fwnode;
> +
> + return software_node_get(parent);
> +}
> +
> +static int
> +software_node_graph_parse_endpoint(const struct fwnode_handle *fwnode,
> +struct fwnode_endpoint *endpoint)
> +{
> + struct swnode *swnode = to_swnode(fwnode);
> + int ret;
> +
> + ret = kstrtou32(swnode->parent->node->name + 5, 10, >port);
> + if (ret)
> + return ret;
> +
> + endpoint->id = swnode->id;
> + endpoint->local_fwnode = fwnode;
> +
> + return 0;
> +}
> +
>  static const struct fwnode_operations software_node_ops = {
>   .get = software_node_get,
>   .put = software_node_put,
> @@ -551,7 +655,11 @@ static const struct fwnode_operations software_node_ops 
> = {
>   .get_parent = software_node_get_parent,
>   .get_next_child_node = software_node_get_next_child,
>   .get_named_child_node = software_node_get_named_child_node,
> - .get_reference_args = software_node_get_reference_args
> + .get_reference_args = software_node_get_reference_args,
> + .graph_get_next_endpoint = software_node_graph_get_next_endpoint,
> + .graph_get_remote_endpoint = software_node_graph_get_remote_endpoint,
> + .graph_get_port_parent = software_node_graph_get_port_parent,
> + .graph_parse_endpoint = software_node_graph_parse_endpoint,
>  };
>  
>  /* 
> -- */

-- 
Regards,

Laurent Pinchart


Re: [PATCH v2 04/12] software_node: Enforce parent before child ordering of nodes arrays

2020-12-18 Thread Laurent Pinchart
Hi Daniel,

Thank you for the patch.

On Thu, Dec 17, 2020 at 11:43:29PM +, Daniel Scally wrote:
> Registering software_nodes with the .parent member set to point to a
> currently unregistered software_node has the potential for problems,
> so enforce parent -> child ordering in arrays passed in to
> software_node_register_nodes().
> 
> Software nodes that are children of another software node should be
> unregistered before their parent. To allow easy unregistering of an array
> of software_nodes ordered parent to child, reverse the order in which
> software_node_unregister_nodes() unregisters software_nodes.
> 
> Suggested-by: Andy Shevchenko 
> Signed-off-by: Daniel Scally 
> ---
> Changes in v2:
> 
>   - Squashed the patches that originally touched these separately
>   - Updated documentation
> 
>  drivers/base/swnode.c | 43 ++-
>  1 file changed, 30 insertions(+), 13 deletions(-)
> 
> diff --git a/drivers/base/swnode.c b/drivers/base/swnode.c
> index 615a0c93e116..cfd1faea48a7 100644
> --- a/drivers/base/swnode.c
> +++ b/drivers/base/swnode.c
> @@ -692,7 +692,10 @@ swnode_register(const struct software_node *node, struct 
> swnode *parent,
>   * software_node_register_nodes - Register an array of software nodes
>   * @nodes: Zero terminated array of software nodes to be registered
>   *
> - * Register multiple software nodes at once.
> + * Register multiple software nodes at once. If any node in the array
> + * has it's .parent pointer set, then it's parent **must** have been
> + * registered before it is; either outside of this function or by
> + * ordering the array such that parent comes before child.
>   */
>  int software_node_register_nodes(const struct software_node *nodes)
>  {
> @@ -700,33 +703,47 @@ int software_node_register_nodes(const struct 
> software_node *nodes)
>   int i;
>  
>   for (i = 0; nodes[i].name; i++) {
> - ret = software_node_register([i]);
> - if (ret) {
> - software_node_unregister_nodes(nodes);
> - return ret;
> + const struct software_node *parent = nodes[i].parent;
> +
> + if (parent && !software_node_to_swnode(parent)) {
> + ret = -EINVAL;
> + goto err_unregister_nodes;
>   }
> +
> + ret = software_node_register([i]);
> + if (ret)
> + goto err_unregister_nodes;
>   }
>  
>   return 0;
> +
> +err_unregister_nodes:
> + software_node_unregister_nodes(nodes);
> + return ret;
>  }
>  EXPORT_SYMBOL_GPL(software_node_register_nodes);
>  
>  /**
>   * software_node_unregister_nodes - Unregister an array of software nodes
> - * @nodes: Zero terminated array of software nodes to be unregistered
> + * @nodes: Zero terminated array of software nodes to be unregistered.

Not sure if this is needed.

>   *
> - * Unregister multiple software nodes at once.
> + * Unregister multiple software nodes at once. If parent pointers are set up
> + * in any of the software nodes then the array MUST be ordered such that

I'd either replace **must** above with MUST, or use **must** here. I'm
not sure if kerneldoc handles emphasis with **must**, if it does that
seems a bit nicer to me, but it's really up to you.

Reviewed-by: Laurent Pinchart 

> + * parents come before their children.
>   *
> - * NOTE: Be careful using this call if the nodes had parent pointers set up 
> in
> - * them before registering.  If so, it is wiser to remove the nodes
> - * individually, in the correct order (child before parent) instead of 
> relying
> - * on the sequential order of the list of nodes in the array.
> + * NOTE: If you are uncertain whether the array is ordered such that
> + * parents will be unregistered before their children, it is wiser to
> + * remove the nodes individually, in the correct order (child before
> + * parent).
>   */
>  void software_node_unregister_nodes(const struct software_node *nodes)
>  {
> -     int i;
> + unsigned int i = 0;
> +
> + while (nodes[i].name)
> + i++;
>  
> - for (i = 0; nodes[i].name; i++)
> + while (i--)
>   software_node_unregister([i]);
>  }
>  EXPORT_SYMBOL_GPL(software_node_unregister_nodes);

-- 
Regards,

Laurent Pinchart


Re: [PATCH] media: vsp1: Fix an error handling path in the probe function

2020-12-16 Thread Laurent Pinchart
Hi Christophe,

Thank you for the patch.

On Sat, Dec 12, 2020 at 06:41:19PM +0100, Christophe JAILLET wrote:
> A previous 'rcar_fcp_get()' call must be undone in the error handling path,
> as already done in the remove function.
> 
> Fixes: 94fcdf829793 ("[media] v4l: vsp1: Add FCP support")
> Signed-off-by: Christophe JAILLET 

Reviewed-by: Laurent Pinchart 

and queued in my tree for v5.12.

> ---
>  drivers/media/platform/vsp1/vsp1_drv.c | 4 +++-
>  1 file changed, 3 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/media/platform/vsp1/vsp1_drv.c 
> b/drivers/media/platform/vsp1/vsp1_drv.c
> index dc62533cf32c..aa66e4f5f3f3 100644
> --- a/drivers/media/platform/vsp1/vsp1_drv.c
> +++ b/drivers/media/platform/vsp1/vsp1_drv.c
> @@ -882,8 +882,10 @@ static int vsp1_probe(struct platform_device *pdev)
>   }
>  
>  done:
> - if (ret)
> + if (ret) {
>   pm_runtime_disable(>dev);
> + rcar_fcp_put(vsp1->fcp);
> + }
>  
>   return ret;
>  }

-- 
Regards,

Laurent Pinchart


Re: [PATCH v3 2/2] dt-bindings: media: Use graph and video-interfaces schemas

2020-12-16 Thread Laurent Pinchart
Hi Rob,

On Wed, Dec 16, 2020 at 11:38:41AM -0600, Rob Herring wrote:
> On Wed, Dec 16, 2020 at 05:19:55PM +0200, Laurent Pinchart wrote:
> > On Thu, Dec 10, 2020 at 03:16:25PM -0600, Rob Herring wrote:
> > > Now that we have graph and video-interfaces schemas, rework the media
> > > related schemas to use them.
> > > 
> > > Cc: Maxime Ripard 
> > > Cc: Mauro Carvalho Chehab 
> > > Cc: Jacopo Mondi 
> > > Cc: Laurent Pinchart 
> > > Cc: linux-me...@vger.kernel.org
> > > Signed-off-by: Rob Herring 
> > > ---
> 
> 
> > > diff --git a/Documentation/devicetree/bindings/media/i2c/mipi-ccs.yaml 
> > > b/Documentation/devicetree/bindings/media/i2c/mipi-ccs.yaml
> > > index d94bd67ccea1..3657f2f41098 100644
> > > --- a/Documentation/devicetree/bindings/media/i2c/mipi-ccs.yaml
> > > +++ b/Documentation/devicetree/bindings/media/i2c/mipi-ccs.yaml
> > > @@ -73,19 +73,16 @@ properties:
> > >  enum: [ 0, 180 ]
> > > 
> > >port:
> > > -type: object
> > > +$ref: /schemas/graph.yaml#/$defs/port-base
> > > +additionalProperties: false
> > > +
> > >  properties:
> > >endpoint:
> > > -type: object
> > > +$ref: /schemas/media/video-interfaces.yaml#
> > > +unevaluatedProperties: false
> > > +
> > >  properties:
> > > -  link-frequencies:
> > > -$ref: /schemas/types.yaml#/definitions/uint64-array
> > > -description: List of allowed data link frequencies.
> > > -  data-lanes:
> > > -minItems: 1
> > > -maxItems: 8
> > 
> > Don't we need
> > 
> >   link-frequencies: true
> >   data-lanes: true
> > 
> > to convey the fact that those properties are applicable for this device
> > ? This applies to a few locations below too.
> 
> Adding them would convey that to the reader, but wouldn't change the 
> schema validation. We'd have to use 'additionalProperties' instead and 
> also add 'remote-endpoint' everywhere (and 'reg' sometimes). I prefer 
> not doing all that, but if we want it just for purposes of documenting 
> the usage, that's fine.

I'd prefer keeping it to document what properties are applicable. If we
can later find a better way to express it in a way that will be taken
into account during validation, that will be best, but not required now.

> > >bus-type:
> > > -description: The type of the data bus.
> > >  oneOf:
> > >- const: 1 # CSI-2 C-PHY
> > >- const: 3 # CCP2
> > > diff --git a/Documentation/devicetree/bindings/media/i2c/ov5647.yaml 
> > > b/Documentation/devicetree/bindings/media/i2c/ov5647.yaml
> > > index 280c62afae13..3b1ea9da437a 100644
> > > --- a/Documentation/devicetree/bindings/media/i2c/ov5647.yaml
> > > +++ b/Documentation/devicetree/bindings/media/i2c/ov5647.yaml
> > > @@ -31,27 +31,15 @@ properties:
> > >  maxItems: 1
> > > 
> > >port:
> > > -type: object
> > > -description: |-
> > > -  Should contain one endpoint sub-node used to model connection to 
> > > the
> > > -  video receiver according to the specification defined in
> > > -  Documentation/devicetree/bindings/media/video-interfaces.txt.
> > > +$ref: /schemas/graph.yaml#/$defs/port-base
> > > 
> > >  properties:
> > >endpoint:
> > > -type: object
> > > +$ref: /schemas/media/video-interfaces.yaml#
> > > +unevaluatedProperties: false
> > > 
> > >  properties:
> > > -  remote-endpoint:
> > > -description: |-
> > > -  phandle to the video receiver input port.
> > > -
> > > -  clock-noncontinuous:
> > > -type: boolean
> > > -description: |-
> > > -  Set to true to allow MIPI CSI-2 non-continuous clock 
> > > operations.
> > > -
> > > -additionalProperties: false
> > > +  clock-noncontinuous: true
> > > 
> > >  additionalProperties: false
> > > 
> > > diff --git a/Documentation/devicetree/bindings/media/i2c/ov8856.yaml 
> > > b/Documentation/devicetree/bindings/media/i2c/ov8856.yaml
> > > index cde85553fd01..c29b057ae922 100644
> > > --- a/Documentatio

Re: [PATCH v6 5/5] media: i2c: max9286: Configure reverse channel amplitude

2020-12-16 Thread Laurent Pinchart
Hi Jacopo,

Thank you for the patch.

On Tue, Dec 15, 2020 at 06:09:57PM +0100, Jacopo Mondi wrote:
> Adjust the initial reverse channel amplitude parsing from
> firmware interface the 'maxim,reverse-channel-microvolt'
> property.
> 
> This change is required for both rdacm20 and rdacm21 camera
> modules to be correctly probed when used in combination with
> the max9286 deserializer.
> 
> Reviewed-by: Kieran Bingham 
> Signed-off-by: Jacopo Mondi 
> ---
>  drivers/media/i2c/max9286.c | 23 ++-
>  1 file changed, 22 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/media/i2c/max9286.c b/drivers/media/i2c/max9286.c
> index 021309c6dd6f..9b40a4890c4d 100644
> --- a/drivers/media/i2c/max9286.c
> +++ b/drivers/media/i2c/max9286.c
> @@ -163,6 +163,8 @@ struct max9286_priv {
>   unsigned int mux_channel;
>   bool mux_open;
>  
> + u32 reverse_channel_mv;
> +
>   struct v4l2_ctrl_handler ctrls;
>   struct v4l2_ctrl *pixelrate;
>  
> @@ -557,10 +559,14 @@ static int max9286_notify_bound(struct 
> v4l2_async_notifier *notifier,
>* All enabled sources have probed and enabled their reverse control
>* channels:
>*
> +  * - Increase the reverse channel amplitude to compensate for the
> +  *   remote ends high threshold, if not done already
>* - Verify all configuration links are properly detected
>* - Disable auto-ack as communication on the control channel are now
>*   stable.
>*/
> + if (priv->reverse_channel_mv < 170)
> + max9286_reverse_channel_setup(priv, 170);

I'm beginning to wonder if there will be a need in the future to not
increase the reverse channel amplitude (keeping the threshold low on the
remote side). An increased amplitude increases power consumption, and if
the environment isn't noisy, a low amplitude would work. The device tree
would then need to specify both the initial amplitude required by the
remote side, and the desired amplitude after initialization. What do you
think ? Is it overkill ? We don't have to implement this now, so

Reviewed-by: Laurent Pinchart 

but if this feature could be required later, we may want to take into
account in the naming of the new DT property to reflect the fact that it
is the initial value.

>   max9286_check_config_link(priv, priv->source_mask);
>  
>   /*
> @@ -967,7 +973,7 @@ static int max9286_setup(struct max9286_priv *priv)
>* only. This should be disabled after the mux is initialised.
>*/
>   max9286_configure_i2c(priv, true);
> - max9286_reverse_channel_setup(priv, 170);
> + max9286_reverse_channel_setup(priv, priv->reverse_channel_mv);
>  
>   /*
>* Enable GMSL links, mask unused ones and autodetect link
> @@ -1131,6 +1137,7 @@ static int max9286_parse_dt(struct max9286_priv *priv)
>   struct device_node *i2c_mux;
>   struct device_node *node = NULL;
>   unsigned int i2c_mux_mask = 0;
> + u32 reverse_channel_microvolt;
>  
>   /* Balance the of_node_put() performed by of_find_node_by_name(). */
>   of_node_get(dev->of_node);
> @@ -1221,6 +1228,20 @@ static int max9286_parse_dt(struct max9286_priv *priv)
>   }
>   of_node_put(node);
>  
> + /*
> +  * Parse the initial value of the reverse channel amplitude from
> +  * the firmware interface and convert it to millivolts.
> +  *
> +  * Default it to 170mV for backward compatibility with DTBs that do not
> +  * provide the property.
> +  */
> + if (of_property_read_u32(dev->of_node,
> +  "maxim,reverse-channel-microvolt",
> +      _channel_microvolt))
> + priv->reverse_channel_mv = 170;
> + else
> + priv->reverse_channel_mv = reverse_channel_microvolt / 1000U;
> +
>   priv->route_mask = priv->source_mask;
>  
>   return 0;

-- 
Regards,

Laurent Pinchart


Re: [PATCH v6 2/5] dt-bindings: media: max9286: Document 'maxim,reverse-channel-microvolt'

2020-12-16 Thread Laurent Pinchart
On Wed, Dec 16, 2020 at 07:05:34PM +0200, Laurent Pinchart wrote:
> Hi Jacopo,
> 
> Thank you for the patch.
> 
> On Tue, Dec 15, 2020 at 06:09:54PM +0100, Jacopo Mondi wrote:
> > Document the 'reverse-channel-microvolt' vendor property in the
> > bindings document of the max9286 driver.
> > 
> > The newly introduced property allows to specifying the initial
> > configuration of the GMSL reverse control channel to accommodate
> > remote serializers pre-programmed with the high threshold power
> > supply noise immunity enabled.
> > 
> > Reviewed-by: Kieran Bingham 
> > Signed-off-by: Jacopo Mondi 
> 
> Reviewed-by: Laurent Pinchart 
> 
> > ---
> > v5->v6:
> > - Use standard unit suffix 'microvolt' for the custom property
> > - Drop '$ref' as according to 'example-schema.yaml':
> >   "Vendor specific properties having a standard unit suffix don't need a 
> > type."
> > ---
> >  .../bindings/media/i2c/maxim,max9286.yaml | 23 +++
> >  1 file changed, 23 insertions(+)
> > 
> > diff --git a/Documentation/devicetree/bindings/media/i2c/maxim,max9286.yaml 
> > b/Documentation/devicetree/bindings/media/i2c/maxim,max9286.yaml
> > index 9ea827092fdd..b22ba3e0db4a 100644
> > --- a/Documentation/devicetree/bindings/media/i2c/maxim,max9286.yaml
> > +++ b/Documentation/devicetree/bindings/media/i2c/maxim,max9286.yaml
> > @@ -51,6 +51,26 @@ properties:
> >'#gpio-cells':
> >  const: 2
> > 
> > +  maxim,reverse-channel-microvolt:
> > +minimum: 3
> > +maximum: 20
> > +default: 17
> > +description: |
> > +  Initial amplitude of the reverse control channel, in micro volts.
> > +
> > +  The initial amplitude shall be adjusted to a value compatible with 
> > the
> > +  configuration of the connected remote serializer.
> > +
> > +  Some camera modules (for example RDACM20) include an on-board MCU 
> > that
> > +  pre-programs the embedded serializer with power supply noise immunity
> > +  (high-threshold) enabled. A typical value of the deserializer's 
> > reverse
> > +  channel amplitude to communicate with pre-programmed serializers is
> > +  17 micro volts.
> > +
> > +  A typical value for the reverse channel amplitude to communicate with
> > +  a remote serializer whose high-threshold noise immunity is not 
> > enabled
> > +  is 10 micro volts
> > +
> >ports:
> >  type: object
> >  description: |
> > @@ -221,6 +241,7 @@ required:
> >- ports
> >- i2c-mux
> >- gpio-controller
> > +  - maxim,reverse-channel-microvolt

One comment though: You specify a default value above, which isn't very
useful when the property is required. Should we either drop the default
value, or make the property optional ?

> > 
> >  additionalProperties: false
> > 
> > @@ -243,6 +264,8 @@ examples:
> >  gpio-controller;
> >  #gpio-cells = <2>;
> > 
> > +maxim,reverse-channel-microvolt = <17>;
> > +
> >  ports {
> >#address-cells = <1>;
> >#size-cells = <0>;

-- 
Regards,

Laurent Pinchart


Re: [PATCH v6 4/5] media: i2c: max9286: Make channel amplitude programmable

2020-12-16 Thread Laurent Pinchart
On Wed, Dec 16, 2020 at 07:14:25PM +0200, Laurent Pinchart wrote:
> Hi Jacopo,
> 
> Thank you for the patch.
> 
> On Tue, Dec 15, 2020 at 06:09:56PM +0100, Jacopo Mondi wrote:
> > Instrument the function that configures the reverse channel with a
> > programmable amplitude value.
> > 
> > This change serves to prepare to adjust the reverse channel amplitude
> > depending on the remote end high-threshold configuration.
> > 
> > Reviewed-by: Kieran Bingham 
> > Signed-off-by: Jacopo Mondi 
> > ---
> >  drivers/media/i2c/max9286.c | 22 --
> >  1 file changed, 16 insertions(+), 6 deletions(-)
> > 
> > diff --git a/drivers/media/i2c/max9286.c b/drivers/media/i2c/max9286.c
> > index 1cfc8801c0b2..021309c6dd6f 100644
> > --- a/drivers/media/i2c/max9286.c
> > +++ b/drivers/media/i2c/max9286.c
> > @@ -336,19 +336,29 @@ static void max9286_configure_i2c(struct max9286_priv 
> > *priv, bool localack)
> > usleep_range(3000, 5000);
> >  }
> >  
> > -static void max9286_reverse_channel_setup(struct max9286_priv *priv)
> > +static void max9286_reverse_channel_setup(struct max9286_priv *priv,
> > + unsigned int chan_amplitude)
> >  {
> > +   /* Reverse channel transmission time: default to 1. */
> > +   u8 chan_config = MAX9286_REV_TRF(1);
> > +
> > /*
> >  * Reverse channel setup.
> >  *
> >  * - Enable custom reverse channel configuration (through register 0x3f)
> >  *   and set the first pulse length to 35 clock cycles.
> > -* - Increase the reverse channel amplitude to 170mV to accommodate the
> > -*   high threshold enabled by the serializer driver.
> > +* - Adjust reverse channel amplitude: values > 130 are programmed
> > +*   using the additional +100mV REV_AMP_X boost flag
> >  */
> > max9286_write(priv, 0x3f, MAX9286_EN_REV_CFG | MAX9286_REV_FLEN(35));
> > -   max9286_write(priv, 0x3b, MAX9286_REV_TRF(1) | MAX9286_REV_AMP(70) |
> > - MAX9286_REV_AMP_X);
> > +
> > +   if (chan_amplitude > 100) {
> > +   /* It is not possible to express values (100 < x < 130) */
> > +   chan_amplitude = chan_amplitude < 130
> > +  ? 30 : chan_amplitude - 100;
> 
> This could also be written
> 
>   chan_amplitude = min(30, chan_amplitude - 100);

s/min/max/ of course.

> 
> With or without the change,
> 
> Reviewed-by: Laurent Pinchart 
> 
> > +   chan_config |= MAX9286_REV_AMP_X;
> > +   }
> > +   max9286_write(priv, 0x3b, chan_config | 
> > MAX9286_REV_AMP(chan_amplitude));
> > usleep_range(2000, 2500);
> >  }
> >  
> > @@ -957,7 +967,7 @@ static int max9286_setup(struct max9286_priv *priv)
> >  * only. This should be disabled after the mux is initialised.
> >  */
> > max9286_configure_i2c(priv, true);
> > -   max9286_reverse_channel_setup(priv);
> > +   max9286_reverse_channel_setup(priv, 170);
> >  
> > /*
> >  * Enable GMSL links, mask unused ones and autodetect link

-- 
Regards,

Laurent Pinchart


Re: [PATCH v6 4/5] media: i2c: max9286: Make channel amplitude programmable

2020-12-16 Thread Laurent Pinchart
Hi Jacopo,

Thank you for the patch.

On Tue, Dec 15, 2020 at 06:09:56PM +0100, Jacopo Mondi wrote:
> Instrument the function that configures the reverse channel with a
> programmable amplitude value.
> 
> This change serves to prepare to adjust the reverse channel amplitude
> depending on the remote end high-threshold configuration.
> 
> Reviewed-by: Kieran Bingham 
> Signed-off-by: Jacopo Mondi 
> ---
>  drivers/media/i2c/max9286.c | 22 --
>  1 file changed, 16 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/media/i2c/max9286.c b/drivers/media/i2c/max9286.c
> index 1cfc8801c0b2..021309c6dd6f 100644
> --- a/drivers/media/i2c/max9286.c
> +++ b/drivers/media/i2c/max9286.c
> @@ -336,19 +336,29 @@ static void max9286_configure_i2c(struct max9286_priv 
> *priv, bool localack)
>   usleep_range(3000, 5000);
>  }
>  
> -static void max9286_reverse_channel_setup(struct max9286_priv *priv)
> +static void max9286_reverse_channel_setup(struct max9286_priv *priv,
> +   unsigned int chan_amplitude)
>  {
> + /* Reverse channel transmission time: default to 1. */
> + u8 chan_config = MAX9286_REV_TRF(1);
> +
>   /*
>* Reverse channel setup.
>*
>* - Enable custom reverse channel configuration (through register 0x3f)
>*   and set the first pulse length to 35 clock cycles.
> -  * - Increase the reverse channel amplitude to 170mV to accommodate the
> -  *   high threshold enabled by the serializer driver.
> +  * - Adjust reverse channel amplitude: values > 130 are programmed
> +  *   using the additional +100mV REV_AMP_X boost flag
>*/
>   max9286_write(priv, 0x3f, MAX9286_EN_REV_CFG | MAX9286_REV_FLEN(35));
> - max9286_write(priv, 0x3b, MAX9286_REV_TRF(1) | MAX9286_REV_AMP(70) |
> -   MAX9286_REV_AMP_X);
> +
> + if (chan_amplitude > 100) {
> + /* It is not possible to express values (100 < x < 130) */
> + chan_amplitude = chan_amplitude < 130
> +? 30 : chan_amplitude - 100;

This could also be written

chan_amplitude = min(30, chan_amplitude - 100);

With or without the change,

Reviewed-by: Laurent Pinchart 

> + chan_config |= MAX9286_REV_AMP_X;
> + }
> + max9286_write(priv, 0x3b, chan_config | 
> MAX9286_REV_AMP(chan_amplitude));
>   usleep_range(2000, 2500);
>  }
>  
> @@ -957,7 +967,7 @@ static int max9286_setup(struct max9286_priv *priv)
>* only. This should be disabled after the mux is initialised.
>*/
>   max9286_configure_i2c(priv, true);
> - max9286_reverse_channel_setup(priv);
> + max9286_reverse_channel_setup(priv, 170);
>  
>   /*
>* Enable GMSL links, mask unused ones and autodetect link

-- 
Regards,

Laurent Pinchart


Re: [PATCH v6 3/5] media: i2c: max9286: Break-out reverse channel setup

2020-12-16 Thread Laurent Pinchart
Hi Jacopo,

Thank you for the patch.

On Tue, Dec 15, 2020 at 06:09:55PM +0100, Jacopo Mondi wrote:
> Break out the reverse channel setup configuration procedure to its own
> function.
> 
> This change prepares for configuring the reverse channel conditionally
> to the remote side high threshold configuration.
> 
> No functional changes intended.
> 
> Reviewed-by: Kieran Bingham 
> Signed-off-by: Jacopo Mondi 

Reviewed-by: Laurent Pinchart 

> ---
>  drivers/media/i2c/max9286.c | 30 +-
>  1 file changed, 17 insertions(+), 13 deletions(-)
> 
> diff --git a/drivers/media/i2c/max9286.c b/drivers/media/i2c/max9286.c
> index c82c1493e099..1cfc8801c0b2 100644
> --- a/drivers/media/i2c/max9286.c
> +++ b/drivers/media/i2c/max9286.c
> @@ -336,6 +336,22 @@ static void max9286_configure_i2c(struct max9286_priv 
> *priv, bool localack)
>   usleep_range(3000, 5000);
>  }
>  
> +static void max9286_reverse_channel_setup(struct max9286_priv *priv)
> +{
> + /*
> +  * Reverse channel setup.
> +  *
> +  * - Enable custom reverse channel configuration (through register 0x3f)
> +  *   and set the first pulse length to 35 clock cycles.
> +  * - Increase the reverse channel amplitude to 170mV to accommodate the
> +  *   high threshold enabled by the serializer driver.
> +  */
> + max9286_write(priv, 0x3f, MAX9286_EN_REV_CFG | MAX9286_REV_FLEN(35));
> + max9286_write(priv, 0x3b, MAX9286_REV_TRF(1) | MAX9286_REV_AMP(70) |
> +   MAX9286_REV_AMP_X);
> + usleep_range(2000, 2500);
> +}
> +
>  /*
>   * max9286_check_video_links() - Make sure video links are detected and 
> locked
>   *
> @@ -941,19 +957,7 @@ static int max9286_setup(struct max9286_priv *priv)
>* only. This should be disabled after the mux is initialised.
>*/
>   max9286_configure_i2c(priv, true);
> -
> - /*
> -  * Reverse channel setup.
> -  *
> -  * - Enable custom reverse channel configuration (through register 0x3f)
> -  *   and set the first pulse length to 35 clock cycles.
> -  * - Increase the reverse channel amplitude to 170mV to accommodate the
> -  *   high threshold enabled by the serializer driver.
> -  */
> - max9286_write(priv, 0x3f, MAX9286_EN_REV_CFG | MAX9286_REV_FLEN(35));
> - max9286_write(priv, 0x3b, MAX9286_REV_TRF(1) | MAX9286_REV_AMP(70) |
> -   MAX9286_REV_AMP_X);
> - usleep_range(2000, 2500);
> + max9286_reverse_channel_setup(priv);
>  
>   /*
>* Enable GMSL links, mask unused ones and autodetect link

-- 
Regards,

Laurent Pinchart


Re: [PATCH v6 2/5] dt-bindings: media: max9286: Document 'maxim,reverse-channel-microvolt'

2020-12-16 Thread Laurent Pinchart
Hi Jacopo,

Thank you for the patch.

On Tue, Dec 15, 2020 at 06:09:54PM +0100, Jacopo Mondi wrote:
> Document the 'reverse-channel-microvolt' vendor property in the
> bindings document of the max9286 driver.
> 
> The newly introduced property allows to specifying the initial
> configuration of the GMSL reverse control channel to accommodate
> remote serializers pre-programmed with the high threshold power
> supply noise immunity enabled.
> 
> Reviewed-by: Kieran Bingham 
> Signed-off-by: Jacopo Mondi 

Reviewed-by: Laurent Pinchart 

> ---
> v5->v6:
> - Use standard unit suffix 'microvolt' for the custom property
> - Drop '$ref' as according to 'example-schema.yaml':
>   "Vendor specific properties having a standard unit suffix don't need a 
> type."
> ---
>  .../bindings/media/i2c/maxim,max9286.yaml | 23 +++
>  1 file changed, 23 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/media/i2c/maxim,max9286.yaml 
> b/Documentation/devicetree/bindings/media/i2c/maxim,max9286.yaml
> index 9ea827092fdd..b22ba3e0db4a 100644
> --- a/Documentation/devicetree/bindings/media/i2c/maxim,max9286.yaml
> +++ b/Documentation/devicetree/bindings/media/i2c/maxim,max9286.yaml
> @@ -51,6 +51,26 @@ properties:
>'#gpio-cells':
>  const: 2
> 
> +  maxim,reverse-channel-microvolt:
> +minimum: 3
> +maximum: 20
> +default: 17
> +description: |
> +  Initial amplitude of the reverse control channel, in micro volts.
> +
> +  The initial amplitude shall be adjusted to a value compatible with the
> +  configuration of the connected remote serializer.
> +
> +  Some camera modules (for example RDACM20) include an on-board MCU that
> +  pre-programs the embedded serializer with power supply noise immunity
> +  (high-threshold) enabled. A typical value of the deserializer's reverse
> +  channel amplitude to communicate with pre-programmed serializers is
> +  17 micro volts.
> +
> +  A typical value for the reverse channel amplitude to communicate with
> +  a remote serializer whose high-threshold noise immunity is not enabled
> +  is 10 micro volts
> +
>ports:
>  type: object
>  description: |
> @@ -221,6 +241,7 @@ required:
>- ports
>- i2c-mux
>- gpio-controller
> +  - maxim,reverse-channel-microvolt
> 
>  additionalProperties: false
> 
> @@ -243,6 +264,8 @@ examples:
>  gpio-controller;
>  #gpio-cells = <2>;
> 
> +maxim,reverse-channel-microvolt = <17>;
> +
>  ports {
>#address-cells = <1>;
>#size-cells = <0>;

-- 
Regards,

Laurent Pinchart


Re: [PATCH v6 1/5] media: i2c: Add driver for RDACM21 camera module

2020-12-16 Thread Laurent Pinchart
Hi Jacopo,

Thank you for the patch.

On Tue, Dec 15, 2020 at 06:09:53PM +0100, Jacopo Mondi wrote:
> The RDACM21 is a GMSL camera supporting 1280x1080 resolution images
> developed by IMI based on an Omnivision OV10640 sensor, an Omnivision
> OV490 ISP and a Maxim MAX9271 GMSL serializer.
> 
> The driver uses the max9271 library module, to maximize code reuse with
> other camera module drivers using the same serializer, such as rdacm20.
> 
> Signed-off-by: Jacopo Mondi 
> ---
>  MAINTAINERS |  12 +
>  drivers/media/i2c/Kconfig   |  13 +
>  drivers/media/i2c/Makefile  |   2 +
>  drivers/media/i2c/rdacm21.c | 595 
>  4 files changed, 622 insertions(+)
>  create mode 100644 drivers/media/i2c/rdacm21.c
> 
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 4be038f0a59d..a011df5a14d7 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -14809,6 +14809,18 @@ F:   drivers/media/i2c/max9271.c
>  F:   drivers/media/i2c/max9271.h
>  F:   drivers/media/i2c/rdacm20.c
>  
> +RDACM21 Camera Sensor
> +M:   Jacopo Mondi 
> +M:   Kieran Bingham 
> +M:   Laurent Pinchart 
> +M:   Niklas Söderlund 
> +L:   linux-me...@vger.kernel.org
> +S:   Maintained
> +F:   Documentation/devicetree/bindings/media/i2c/rdacm2x-gmsl.yaml
> +F:   drivers/media/i2c/max9271.c
> +F:   drivers/media/i2c/max9271.h
> +F:   drivers/media/i2c/rdacm21.c
> +
>  RDC R-321X SoC
>  M:   Florian Fainelli 
>  S:   Maintained
> diff --git a/drivers/media/i2c/Kconfig b/drivers/media/i2c/Kconfig
> index 2b9d81e4794a..d500edb8638b 100644
> --- a/drivers/media/i2c/Kconfig
> +++ b/drivers/media/i2c/Kconfig
> @@ -1212,6 +1212,19 @@ config VIDEO_RDACM20
> This camera should be used in conjunction with a GMSL
> deserialiser such as the MAX9286.
>  
> +config VIDEO_RDACM21
> + tristate "IMI RDACM21 camera support"
> + depends on I2C
> + select V4L2_FWNODE
> + select VIDEO_V4L2_SUBDEV_API
> + select MEDIA_CONTROLLER
> + help
> +   This driver supports the IMI RDACM21 GMSL camera, used in
> +   ADAS systems.
> +
> +   This camera should be used in conjunction with a GMSL
> +   deserialiser such as the MAX9286.
> +
>  config VIDEO_RJ54N1
>   tristate "Sharp RJ54N1CB0C sensor support"
>   depends on I2C && VIDEO_V4L2
> diff --git a/drivers/media/i2c/Makefile b/drivers/media/i2c/Makefile
> index a3149dce21bb..85b1edc62508 100644
> --- a/drivers/media/i2c/Makefile
> +++ b/drivers/media/i2c/Makefile
> @@ -124,6 +124,8 @@ obj-$(CONFIG_VIDEO_IMX355)+= imx355.o
>  obj-$(CONFIG_VIDEO_MAX9286)  += max9286.o
>  rdacm20-camera_module-objs   := rdacm20.o max9271.o
>  obj-$(CONFIG_VIDEO_RDACM20)  += rdacm20-camera_module.o
> +rdacm21-camera_module-objs   := rdacm21.o max9271.o
> +obj-$(CONFIG_VIDEO_RDACM21)  += rdacm21-camera_module.o
>  obj-$(CONFIG_VIDEO_ST_MIPID02) += st-mipid02.o
>  
>  obj-$(CONFIG_SDR_MAX2175) += max2175.o
> diff --git a/drivers/media/i2c/rdacm21.c b/drivers/media/i2c/rdacm21.c
> new file mode 100644
> index ..5f9267e26258
> --- /dev/null
> +++ b/drivers/media/i2c/rdacm21.c
> @@ -0,0 +1,595 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +/*
> + * IMI RDACM21 GMSL Camera Driver
> + *
> + * Copyright (C) 2017-2020 Jacopo Mondi
> + * Copyright (C) 2017-2019 Kieran Bingham
> + * Copyright (C) 2017-2019 Laurent Pinchart
> + * Copyright (C) 2017-2019 Niklas Söderlund
> + * Copyright (C) 2016 Renesas Electronics Corporation
> + * Copyright (C) 2015 Cogent Embedded, Inc.
> + */
> +
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +
> +#include 
> +#include 
> +#include 
> +#include "max9271.h"
> +
> +#define OV10640_ID_LOW   0xa6
> +
> +#define OV490_I2C_ADDRESS0x24
> +
> +#define OV490_PAGE_HIGH_REG  0xfffd
> +#define OV490_PAGE_LOW_REG   0xfffe
> +
> +#define OV490_DVP_CTRL3  0x80286009
> +
> +#define OV490_ODS_CTRL_FRAME_OUTPUT_EN   0x0c
> +#define OV490_ODS_CTRL   0x8029d000
> +
> +#define OV490_ID_VAL 0x0490
> +#define OV490_ID(_p, _v) _p) & 0xff) << 8) | ((_v) & 0xff))
> +#define OV490_PID0x8080300a
> +#define OV490_VER0x8080300b
> +
> +#define OV490_ISP_HSIZE_LOW  0x80820060
> +#define OV490_ISP_HSIZE_HIGH 0x80820061
> +#define OV490_ISP_VSIZE_LOW  0x80820062
> +#define OV490_ISP_VSIZE_HIGH 0x80820063
> +
> +#define OV10640_PIXEL_RATE   (55

Re: [PATCH v3 2/2] dt-bindings: media: Use graph and video-interfaces schemas

2020-12-16 Thread Laurent Pinchart
Hi Rob,

Thank you for the patch.

On Thu, Dec 10, 2020 at 03:16:25PM -0600, Rob Herring wrote:
> Now that we have graph and video-interfaces schemas, rework the media
> related schemas to use them.
> 
> Cc: Maxime Ripard 
> Cc: Mauro Carvalho Chehab 
> Cc: Jacopo Mondi 
> Cc: Laurent Pinchart 
> Cc: linux-me...@vger.kernel.org
> Signed-off-by: Rob Herring 
> ---
> v3:
>  - Add mipi-ccs.yaml, ovti,ov02a10.yaml
> 
> v2:
>  - Update based on graph schema changes and addition of video-interfaces
>schemas
> 
> ---
>  .../media/allwinner,sun4i-a10-csi.yaml|  11 +-
>  .../media/allwinner,sun6i-a31-csi.yaml|  12 +-
>  .../bindings/media/i2c/adv7180.yaml   |  36 ++
>  .../bindings/media/i2c/adv7604.yaml   |  37 ++
>  .../bindings/media/i2c/aptina,mt9v111.yaml|   4 +-
>  .../bindings/media/i2c/imi,rdacm2x-gmsl.yaml  |  30 +
>  .../devicetree/bindings/media/i2c/imx219.yaml |  21 ++--
>  .../bindings/media/i2c/maxim,max9286.yaml | 101 
>  .../bindings/media/i2c/mipi-ccs.yaml  |  15 +--
>  .../devicetree/bindings/media/i2c/ov5647.yaml |  20 +---
>  .../devicetree/bindings/media/i2c/ov8856.yaml |  21 +---
>  .../bindings/media/i2c/ovti,ov02a10.yaml  |  30 ++---
>  .../bindings/media/i2c/ovti,ov2680.yaml   |   6 +-
>  .../bindings/media/i2c/ovti,ov772x.yaml   |   9 +-
>  .../bindings/media/i2c/sony,imx214.yaml   |  25 ++--
>  .../bindings/media/i2c/sony,imx274.yaml   |   3 +-
>  .../bindings/media/marvell,mmp2-ccic.yaml |  15 +--
>  .../bindings/media/nxp,imx7-csi.yaml  |   5 +-
>  .../bindings/media/nxp,imx7-mipi-csi2.yaml|  32 +
>  .../bindings/media/renesas,ceu.yaml   |  17 +--
>  .../bindings/media/renesas,csi2.yaml  |  54 ++---
>  .../bindings/media/renesas,vin.yaml   | 113 +++---
>  .../bindings/media/rockchip-isp1.yaml |  40 +--
>  .../bindings/media/st,stm32-dcmi.yaml |  18 +--
>  .../devicetree/bindings/media/ti,cal.yaml |  55 ++---
>  .../bindings/media/xilinx/xlnx,csi2rxss.yaml  |  39 +-
>  26 files changed, 169 insertions(+), 600 deletions(-)
> 
> diff --git 
> a/Documentation/devicetree/bindings/media/allwinner,sun4i-a10-csi.yaml 
> b/Documentation/devicetree/bindings/media/allwinner,sun4i-a10-csi.yaml
> index 09318830db47..6ced94064215 100644
> --- a/Documentation/devicetree/bindings/media/allwinner,sun4i-a10-csi.yaml
> +++ b/Documentation/devicetree/bindings/media/allwinner,sun4i-a10-csi.yaml
> @@ -67,14 +67,14 @@ properties:
>interconnect-names:
>  const: dma-mem
> 
> -  # See ./video-interfaces.txt for details
>port:
> -type: object
> +$ref: /schemas/graph.yaml#/$defs/port-base
>  additionalProperties: false
> 
>  properties:
>endpoint:
> -type: object
> +$ref: video-interfaces.yaml#
> +unevaluatedProperties: false
> 
>  properties:
>bus-width:
> @@ -83,7 +83,6 @@ properties:
>data-active: true
>hsync-active: true
>pclk-sample: true
> -  remote-endpoint: true
>vsync-active: true
> 
>  required:
> @@ -91,12 +90,8 @@ properties:
>- data-active
>- hsync-active
>- pclk-sample
> -  - remote-endpoint
>- vsync-active
> 
> -required:
> -  - endpoint
> -
>  required:
>- compatible
>- reg
> diff --git 
> a/Documentation/devicetree/bindings/media/allwinner,sun6i-a31-csi.yaml 
> b/Documentation/devicetree/bindings/media/allwinner,sun6i-a31-csi.yaml
> index 1fd9b5532a21..8b568072a069 100644
> --- a/Documentation/devicetree/bindings/media/allwinner,sun6i-a31-csi.yaml
> +++ b/Documentation/devicetree/bindings/media/allwinner,sun6i-a31-csi.yaml
> @@ -40,17 +40,15 @@ properties:
>resets:
>  maxItems: 1
> 
> -  # See ./video-interfaces.txt for details
>port:
> -type: object
> +$ref: /schemas/graph.yaml#/$defs/port-base
> 
>  properties:
>endpoint:
> -type: object
> +$ref: video-interfaces.yaml#
> +unevaluatedProperties: false
> 
>  properties:
> -  remote-endpoint: true
> -
>bus-width:
>  enum: [ 8, 10, 12, 16 ]
> 
> @@ -60,10 +58,6 @@ properties:
> 
>  required:
>- bus-width
> -  - remote-endpoint
> -
> -required:
> -  - endpoint
> 
>  additionalProperties: false
> 
> diff --git a/Documentation/devicetree/bindings/media/i2c/adv7180.yaml 
> b/Documentation/devicetree/bindings/media/i2c/adv7180.yaml
&

Re: [PATCH v3 1/2] media: dt-bindings: Convert video-interfaces.txt properties to schemas

2020-12-16 Thread Laurent Pinchart
Hi Rob,

Thank you for the patch.

On Thu, Dec 10, 2020 at 03:16:24PM -0600, Rob Herring wrote:
> Convert video-interfaces.txt to DT schema. As it contains a mixture of
> device level and endpoint properties, split it up into 2 schemas.
> 
> Binding schemas will need to reference both the graph.yaml and
> video-interfaces.yaml schemas. The exact schema depends on how many
> ports and endpoints for the binding. A single port with a single
> endpoint looks similar to this:
> 
>   port:
> $ref: /schemas/graph.yaml#/$defs/port-base
> 
> properties:
>   endpoint:
> $ref: video-interfaces.yaml#
> unevaluatedProperties: false
> 
> properties:
>   bus-width:
> enum: [ 8, 10, 12, 16 ]
> 
>   pclk-sample: true
>   hsync-active: true
>   vsync-active: true
> 
> required:
>   - bus-width
> 
> additionalProperties: false
> 
> Cc: Guennadi Liakhovetski 
> Acked-by: Sakari Ailus 
> Acked-by: Jacopo Mondi 
> Signed-off-by: Rob Herring 
> ---
> I need acks for dual licensing from the listed maintainers.
> 
> v3:
> - Support up to 9 physical lanes
> - Set lane-polarities array bounds
> ---
>  .../media/video-interface-devices.yaml| 406 +++
>  .../bindings/media/video-interfaces.txt   | 640 +-
>  .../bindings/media/video-interfaces.yaml  | 346 ++
>  3 files changed, 753 insertions(+), 639 deletions(-)
>  create mode 100644 
> Documentation/devicetree/bindings/media/video-interface-devices.yaml
>  create mode 100644 
> Documentation/devicetree/bindings/media/video-interfaces.yaml
> 
> diff --git 
> a/Documentation/devicetree/bindings/media/video-interface-devices.yaml 
> b/Documentation/devicetree/bindings/media/video-interface-devices.yaml
> new file mode 100644
> index ..4527f56a5a6e
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/media/video-interface-devices.yaml
> @@ -0,0 +1,406 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/media/video-interface-devices.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Common bindings for video receiver and transmitter devices
> +
> +maintainers:
> +  - Jacopo Mondi 
> +  - Sakari Ailus 
> +
> +properties:
> +  flash-leds:
> +$ref: /schemas/types.yaml#/definitions/phandle-array
> +description:
> +  An array of phandles, each referring to a flash LED, a sub-node of the 
> LED
> +  driver device node.
> +
> +  lens-focus:
> +$ref: /schemas/types.yaml#/definitions/phandle
> +description:
> +  A phandle to the node of the focus lens controller.
> +
> +  rotation:
> +$ref: /schemas/types.yaml#/definitions/uint32
> +enum: [ 0, 90, 180, 270 ]
> +description: |
> +  The camera rotation is expressed as the angular difference in degrees
> +  between two reference systems, one relative to the camera module, and 
> one
> +  defined on the external world scene to be captured when projected on 
> the
> +  image sensor pixel array.
> +
> +  A camera sensor has a 2-dimensional reference system 'Rc' defined by 
> its
> +  pixel array read-out order. The origin is set to the first pixel being
> +  read out, the X-axis points along the column read-out direction towards
> +  the last columns, and the Y-axis along the row read-out direction 
> towards
> +  the last row.
> +
> +  A typical example for a sensor with a 2592x1944 pixel array matrix
> +  observed from the front is:
> +
> +  2591   X-axis  0
> +<+ 0
> +.. ... ..!
> +.. ... ..! Y-axis
> +   ...   !
> +.. ... ..!
> +.. ... ..! 1943
> + V
> +
> +  The external world scene reference system 'Rs' is a 2-dimensional
> +  reference system on the focal plane of the camera module. The origin is
> +  placed on the top-left corner of the visible scene, the X-axis points
> +  towards the right, and the Y-axis points towards the bottom of the 
> scene.
> +  The top, bottom, left and right directions are intentionally not 
> defined
> +  and depend on the environment in which the camera is used.
> +
> +  A typical example of a (very common) picture of a shark swimming from 
> left
> +  to right, as seen from the camera, is:
> +
> +   0   X-axis
> + 0 +->
> +   !
> +   !
> +   !
> +   !   |\)\___
> +   !   ) _  __`<
> +   !   |/ )/
> +   !
> +   !
> +   !
> +   V
> + Y-axis
> +
> + 

Re: [PATCH v2 1/2] media: dt-bindings: Convert video-interfaces.txt properties to schemas

2020-12-16 Thread Laurent Pinchart
Hi Rob,

On Wed, Dec 16, 2020 at 08:12:10AM -0600, Rob Herring wrote:
> On Wed, Dec 16, 2020 at 11:18:03AM +0100, Guennadi Liakhovetski wrote:
> > Hi Rob,
> > 
> > Sorry for the delay! I didn't realise my ack was required for this patch.
> > I won't object against the licence change, but please don't add me as a
> > maintainer of
> 
> Okay, so that's an Ack?
> 
> > 
> > On Thu, 10 Dec 2020, Rob Herring wrote:
> > 
> > [snip]
> > 
> > > diff --git 
> > > a/Documentation/devicetree/bindings/media/video-interfaces.yaml 
> > > b/Documentation/devicetree/bindings/media/video-interfaces.yaml
> > > new file mode 100644
> > > index ..7415a4df1576
> > > --- /dev/null
> > > +++ b/Documentation/devicetree/bindings/media/video-interfaces.yaml
> > > @@ -0,0 +1,344 @@
> > > +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> > > +%YAML 1.2
> > > +---
> > > +$id: http://devicetree.org/schemas/media/video-interfaces.yaml#
> > > +$schema: http://devicetree.org/meta-schemas/core.yaml#
> > > +
> > > +title: Common bindings for video receiver and transmitter interface 
> > > endpoints
> > > +
> > > +maintainers:
> > > +  - Guennadi Liakhovetski 
> > 
> > I did commit the original version of
> > Documentation/devicetree/bindings/media/video-interfaces.txt but that was
> > more than 8 years ago, I haven't worked in media / V4L for several years
> > now, so, I don't think I can meaningfully maintain that file now.
> 
> Okay, I'll drop you.
> 
> Anyone else want to sign up? Laurent?

I'll likely regret this, but yes, you can sign me up :-)

-- 
Regards,

Laurent Pinchart


Re: [PATCH] drm: rcar-du: fix reference leak in rcar_cmm_enable

2020-12-15 Thread Laurent Pinchart
Hi Qinglang,

Thank you for the patch.

On Fri, Nov 27, 2020 at 05:44:44PM +0800, Qinglang Miao wrote:
> pm_runtime_get_sync will increment pm usage counter even it
> failed. Forgetting to putting operation will result in a
> reference leak here.
> 
> A new function pm_runtime_resume_and_get is introduced in
> [0] to keep usage counter balanced. So We fix the reference
> leak by replacing it with new funtion.
> 
> [0] dd8088d5a896 ("PM: runtime: Add  pm_runtime_resume_and_get to deal with 
> usage counter")
> 
> Fixes: e08e934d6c28 ("drm: rcar-du: Add support for CMM")
> Reported-by: Hulk Robot 
> Signed-off-by: Qinglang Miao 

Reviewed-by: Laurent Pinchart 

And queued for v5.11.

> ---
>  drivers/gpu/drm/rcar-du/rcar_cmm.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/rcar-du/rcar_cmm.c 
> b/drivers/gpu/drm/rcar-du/rcar_cmm.c
> index c578095b0..382d53f8a 100644
> --- a/drivers/gpu/drm/rcar-du/rcar_cmm.c
> +++ b/drivers/gpu/drm/rcar-du/rcar_cmm.c
> @@ -122,7 +122,7 @@ int rcar_cmm_enable(struct platform_device *pdev)
>  {
>   int ret;
>  
> - ret = pm_runtime_get_sync(>dev);
> +     ret = pm_runtime_resume_and_get(>dev);
>   if (ret < 0)
>   return ret;
>  

-- 
Regards,

Laurent Pinchart


Re: [net-next PATCH v2 10/14] device property: Introduce fwnode_get_id()

2020-12-15 Thread Laurent Pinchart
Hi Calvin,

Thank you for the patch.

On Tue, Dec 15, 2020 at 10:13:11PM +0530, Calvin Johnson wrote:
> Using fwnode_get_id(), get the reg property value for DT node
> and get the _ADR object value for ACPI node.
> 
> Signed-off-by: Calvin Johnson 
> ---
> 
> Changes in v2: None
> 
>  drivers/base/property.c  | 26 ++
>  include/linux/property.h |  1 +
>  2 files changed, 27 insertions(+)
> 
> diff --git a/drivers/base/property.c b/drivers/base/property.c
> index 4c43d30145c6..1c50e17ae879 100644
> --- a/drivers/base/property.c
> +++ b/drivers/base/property.c
> @@ -580,6 +580,32 @@ const char *fwnode_get_name_prefix(const struct 
> fwnode_handle *fwnode)
>   return fwnode_call_ptr_op(fwnode, get_name_prefix);
>  }
>  
> +/**
> + * fwnode_get_id - Get the id of a fwnode.
> + * @fwnode: firmware node
> + * @id: id of the fwnode
> + *

Is the concept of fwnode ID documented clearly somewhere ? I think this
function should otherwise have more documentation, at least to explain
what the ID is.

> + * Returns 0 on success or a negative errno.
> + */
> +int fwnode_get_id(struct fwnode_handle *fwnode, u32 *id)
> +{
> + unsigned long long adr;
> + acpi_status status;
> +
> + if (is_of_node(fwnode)) {
> + return of_property_read_u32(to_of_node(fwnode), "reg", id);
> + } else if (is_acpi_node(fwnode)) {
> + status = acpi_evaluate_integer(ACPI_HANDLE_FWNODE(fwnode),
> +METHOD_NAME__ADR, NULL, );
> + if (ACPI_FAILURE(status))
> + return -ENODATA;

Would it make sense to standardize error codes ? of_property_read_u32()
can return -EINVAL, -ENODATA or -EOVERFLOW. I don't think the caller of
this function would be very interested to tell those three cases apart.
Maybe we should return -EINVAL in all error cases ? Or maybe different
error codes to mean "the backend doesn't support the concept of IDs",
and "the device doesn't have an ID" ?

> + *id = (u32)adr;
> + return 0;
> + }
> + return -EINVAL;
> +}
> +EXPORT_SYMBOL_GPL(fwnode_get_id);
> +
>  /**
>   * fwnode_get_parent - Return parent firwmare node
>   * @fwnode: Firmware whose parent is retrieved
> diff --git a/include/linux/property.h b/include/linux/property.h
> index 2d4542629d80..92d405cf2b07 100644
> --- a/include/linux/property.h
> +++ b/include/linux/property.h
> @@ -82,6 +82,7 @@ struct fwnode_handle *fwnode_find_reference(const struct 
> fwnode_handle *fwnode,
>  
>  const char *fwnode_get_name(const struct fwnode_handle *fwnode);
>  const char *fwnode_get_name_prefix(const struct fwnode_handle *fwnode);
> +int fwnode_get_id(struct fwnode_handle *fwnode, u32 *id);
>  struct fwnode_handle *fwnode_get_parent(const struct fwnode_handle *fwnode);
>  struct fwnode_handle *fwnode_get_next_parent(
>   struct fwnode_handle *fwnode);

-- 
Regards,

Laurent Pinchart


Re: [PATCH] drivers: usb: gadget: prefer pr_*() functions over raw printk()

2020-12-09 Thread Laurent Pinchart
Hi Enrico,

On Wed, Dec 09, 2020 at 12:11:36PM +0100, Enrico Weigelt, metux IT consult 
wrote:
> On 08.12.20 16:54, Laurent Pinchart wrote:
> >> diff --git a/drivers/usb/gadget/udc/atmel_usba_udc.c 
> >> b/drivers/usb/gadget/udc/atmel_usba_udc.c
> >> index 2b893bceea45..4834fafb3f70 100644
> >> --- a/drivers/usb/gadget/udc/atmel_usba_udc.c
> >> +++ b/drivers/usb/gadget/udc/atmel_usba_udc.c
> >> @@ -1573,7 +1573,7 @@ static void usba_control_irq(struct usba_udc *udc, 
> >> struct usba_ep *ep)
> >> * generate or receive a reply right away. */
> >>usba_ep_writel(ep, CLR_STA, USBA_RX_SETUP);
> >>  
> >> -  /* printk(KERN_DEBUG "setup: %d: %02x.%02x\n",
> >> +  /* pr_debug("setup: %d: %02x.%02x\n",
> >>ep->state, crq.crq.bRequestType,
> >>crq.crq.bRequest); */
> > 
> > I wonder if this shouldn't be dropped instead, commented-out code isn't
> > very useful.
> 
> Indeed. Shall I send a separate patch for that ?

Yes, that would make sense.

> > When a pointer to a struct device is available, dev_err() would be much
> > better. That's however out of scope for this patch, but it would be nice
> > to address it. This would become
> > 
> > dev_err(>dev, "Check IRQ setup!\n");
> > 
> 
> You're right. I didn't check for that yet. I'll do it in a separate
> patch.

As most of the files touched by this patch are device drivers, dev_*()
functions should be used instead of pr_*() where possible. I'd recommend
a first patch that converts to dev_*(), and then a second patch that
converts the remaining printk()s, if any, to pr_*() in the contexts
where no struct device is available or can easily be made available.

-- 
Regards,

Laurent Pinchart


Re: [PATCH] drivers: usb: gadget: prefer pr_*() functions over raw printk()

2020-12-08 Thread Laurent Pinchart
   FUSB300_IGR1_U1_ENTRY_INT);
> - printk(KERN_INFO "FUSB300_IGR1_U1_ENTRY_INT\n");
> + pr_info("FUSB300_IGR1_U1_ENTRY_INT\n");
>   }
>  
>   if (int_grp1 & FUSB300_IGR1_RESM_INT) {
>   fusb300_clear_int(fusb300, FUSB300_OFFSET_IGR1,
> FUSB300_IGR1_RESM_INT);
> - printk(KERN_INFO "fusb300_resume\n");
> + pr_info("fusb300_resume\n");
>   }
>  
>   if (int_grp1 & FUSB300_IGR1_SUSP_INT) {
>   fusb300_clear_int(fusb300, FUSB300_OFFSET_IGR1,
> FUSB300_IGR1_SUSP_INT);
> - printk(KERN_INFO "fusb300_suspend\n");
> + pr_info("fusb300_suspend\n");
>   }
>  
>   if (int_grp1 & FUSB300_IGR1_HS_LPM_INT) {
>   fusb300_clear_int(fusb300, FUSB300_OFFSET_IGR1,
> FUSB300_IGR1_HS_LPM_INT);
> - printk(KERN_INFO "fusb300_HS_LPM_INT\n");
> + pr_info("fusb300_HS_LPM_INT\n");
>   }
>  
>   if (int_grp1 & FUSB300_IGR1_DEV_MODE_CHG_INT) {
> @@ -1195,11 +1195,11 @@ static irqreturn_t fusb300_irq(int irq, void 
> *_fusb300)
>  
>   if (int_grp1 & FUSB300_IGR1_CX_COMFAIL_INT) {
>   fusb300_set_cxstall(fusb300);
> - printk(KERN_INFO "fusb300_ep0fail\n");
> + pr_info("fusb300_ep0fail\n");
>   }
>  
>   if (int_grp1 & FUSB300_IGR1_CX_SETUP_INT) {
> - printk(KERN_INFO "fusb300_ep0setup\n");
> + pr_info("fusb300_ep0setup\n");
>   if (setup_packet(fusb300, )) {
>   spin_unlock(>lock);
>   if (fusb300->driver->setup(>gadget, ) < 0)
> @@ -1209,16 +1209,16 @@ static irqreturn_t fusb300_irq(int irq, void 
> *_fusb300)
>   }
>  
>   if (int_grp1 & FUSB300_IGR1_CX_CMDEND_INT)
> - printk(KERN_INFO "fusb300_cmdend\n");
> + pr_info("fusb300_cmdend\n");
>  
>  
>   if (int_grp1 & FUSB300_IGR1_CX_OUT_INT) {
> - printk(KERN_INFO "fusb300_cxout\n");
> + pr_info("fusb300_cxout\n");
>   fusb300_ep0out(fusb300);
>   }
>  
>   if (int_grp1 & FUSB300_IGR1_CX_IN_INT) {
> - printk(KERN_INFO "fusb300_cxin\n");
> + pr_info("fusb300_cxin\n");
>   fusb300_ep0in(fusb300);
>   }
>  
> diff --git a/drivers/usb/gadget/udc/goku_udc.c 
> b/drivers/usb/gadget/udc/goku_udc.c
> index 3e1267d38774..4f225552861a 100644
> --- a/drivers/usb/gadget/udc/goku_udc.c
> +++ b/drivers/usb/gadget/udc/goku_udc.c
> @@ -1748,7 +1748,7 @@ static int goku_probe(struct pci_dev *pdev, const 
> struct pci_device_id *id)
>   int retval;
>  
>   if (!pdev->irq) {
> - printk(KERN_ERR "Check PCI %s IRQ setup!\n", pci_name(pdev));
> + pr_err("Check PCI %s IRQ setup!\n", pci_name(pdev));

When a pointer to a struct device is available, dev_err() would be much
better. That's however out of scope for this patch, but it would be nice
to address it. This would become

dev_err(>dev, "Check IRQ setup!\n");

Reviewed-by: Laurent Pinchart 

>   retval = -ENODEV;
>   goto err;
>   }
> diff --git a/drivers/usb/gadget/udc/r8a66597-udc.h 
> b/drivers/usb/gadget/udc/r8a66597-udc.h
> index 9a115caba661..fa4d62c32ea1 100644
> --- a/drivers/usb/gadget/udc/r8a66597-udc.h
> +++ b/drivers/usb/gadget/udc/r8a66597-udc.h
> @@ -247,7 +247,7 @@ static inline u16 get_xtal_from_pdata(struct 
> r8a66597_platdata *pdata)
>   clock = XTAL48;
>   break;
>   default:
> - printk(KERN_ERR "r8a66597: platdata clock is wrong.\n");
> + pr_err("r8a66597: platdata clock is wrong.\n");
>   break;
>   }
>  

-- 
Regards,

Laurent Pinchart


Re: [PATCH 2/4] phy: Add LVDS configuration options

2020-12-08 Thread Laurent Pinchart
Hi Liu,

Thank you for the patch.

On Fri, Dec 04, 2020 at 03:33:42PM +0800, Liu Ying wrote:
> This patch allows LVDS PHYs to be configured through
> the generic functions and through a custom structure
> added to the generic union.
> 
> The parameters added here are based on common LVDS PHY
> implementation practices.  The set of parameters
> should cover all potential users.
> 
> Cc: Kishon Vijay Abraham I 
> Cc: Vinod Koul 
> Cc: NXP Linux Team 
> Signed-off-by: Liu Ying 
> ---
>  include/linux/phy/phy-lvds.h | 48 
> 
>  include/linux/phy/phy.h  |  4 
>  2 files changed, 52 insertions(+)
>  create mode 100644 include/linux/phy/phy-lvds.h
> 
> diff --git a/include/linux/phy/phy-lvds.h b/include/linux/phy/phy-lvds.h
> new file mode 100644
> index ..1b5b9d6
> --- /dev/null
> +++ b/include/linux/phy/phy-lvds.h
> @@ -0,0 +1,48 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +/*
> + * Copyright 2020 NXP
> + */
> +
> +#ifndef __PHY_LVDS_H_
> +#define __PHY_LVDS_H_
> +
> +/**
> + * struct phy_configure_opts_lvds - LVDS configuration set
> + *
> + * This structure is used to represent the configuration state of a
> + * LVDS phy.
> + */
> +struct phy_configure_opts_lvds {
> + /**
> +  * @bits_per_lane_and_dclk_cycle:
> +  *
> +  * Number of bits per data lane and differential clock cycle.
> +  */
> + unsigned int bits_per_lane_and_dclk_cycle;

I see in patch 4/4 that you only support 7, can the value be any
different ?

> +
> + /**
> +  * @differential_clk_rate:
> +  *
> +  * Clock rate, in Hertz, of the LVDS differential clock.
> +  */
> + unsigned long differential_clk_rate;
> +
> + /**
> +  * @lanes:
> +  *
> +  * Number of active, consecutive, data lanes, starting from
> +  * lane 0, used for the transmissions.
> +  */
> + unsigned int lanes;
> +
> + /**
> +  * @is_slave:
> +  *
> +  * Boolean, true if the phy is a slave which works together
> +  * with a master phy to support dual link transmission,
> +  * otherwise a regular phy or a master phy.
> +  */
> + bool is_slave;
> +};
> +
> +#endif /* __PHY_LVDS_H_ */
> diff --git a/include/linux/phy/phy.h b/include/linux/phy/phy.h
> index e435bdb..d450b44 100644
> --- a/include/linux/phy/phy.h
> +++ b/include/linux/phy/phy.h
> @@ -17,6 +17,7 @@
>  #include 
>  
>  #include 
> +#include 
>  #include 
>  
>  struct phy;
> @@ -51,10 +52,13 @@ enum phy_mode {
>   *   the MIPI_DPHY phy mode.
>   * @dp:  Configuration set applicable for phys supporting
>   *   the DisplayPort protocol.
> + * @lvds:Configuration set applicable for phys supporting
> + *   the LVDS phy mode.
>   */
>  union phy_configure_opts {
>   struct phy_configure_opts_mipi_dphy mipi_dphy;
>   struct phy_configure_opts_dpdp;
> + struct phy_configure_opts_lvds  lvds;
>  };
>  
>  /**

-- 
Regards,

Laurent Pinchart


Re: [PATCH 06/12] arm64: dts: zynqmp: Add label for zynqmp_ipi

2020-12-07 Thread Laurent Pinchart
Hi Michal,

On Mon, Dec 07, 2020 at 10:39:25AM +0100, Michal Simek wrote:
> On 06. 12. 20 23:46, Laurent Pinchart wrote:
> > On Wed, Dec 02, 2020 at 03:06:05PM +0100, Michal Simek wrote:
> >> Add label which is used by bootloader for adding bootloader specific flag.
> >>
> >> Signed-off-by: Michal Simek 
> >> ---
> >>
> >> U-Boot needs to add u-boot,dm-pre-reloc; property
> > 
> > I'm not entirely sure what best practice rules are in this area, but
> > shouldn't U-Boot locate the node by name instead of label ?
> 
> Labels are not listed in dt binding and there are two approaches how to
> reference nodes. Via full path with node name or via labels.
> I do normally use labels which are much simple.

Note that labels require the DTB to be compiled with the -@ option,
otherwise they're not present in the binary.

> And also if you take a look how dtb looks like (convert back to dts) you
> can see that for example aliases are using full path (just ) but
> clocks/gic which is the part of <> is handled via phandles as numbers.
> 
> And labels names can vary and shouldn't be the part of binding doc as
> far as I know. But I can be wrong of course.

The DT bindings should document the interface with the operating system,
and if applicable, the boot loader. If the boot loader requires a
particular label, then it becomes part of the ABI, and I think it should
be documented in the bindings.

-- 
Regards,

Laurent Pinchart


Re: [PATCH] media: ti-vpe: cal: avoid FIELD_GET assertion

2020-12-06 Thread Laurent Pinchart
Hi Arnd,

Thank you for the patch.

On Fri, Dec 04, 2020 at 12:07:30AM +0100, Arnd Bergmann wrote:
> From: Arnd Bergmann 
> 
> FIELD_GET() must only be used with a mask that is a compile-time
> constant:
> 
> drivers/media/platform/ti-vpe/cal.h: In function 'cal_read_field':
> include/linux/compiler_types.h:320:38: error: call to 
> '__compiletime_assert_247' declared with attribute error: FIELD_GET: mask is 
> not constant
> include/linux/bitfield.h:46:3: note: in expansion of macro 'BUILD_BUG_ON_MSG'
>46 |   BUILD_BUG_ON_MSG(!__builtin_constant_p(_mask),  \
>   |   ^~~~
> drivers/media/platform/ti-vpe/cal.h:220:9: note: in expansion of macro 
> 'FIELD_GET'
>   220 |  return FIELD_GET(mask, cal_read(cal, offset));
>   | ^
> 
> The problem here is that the function is not always inlined. Mark it
> __always_inline to avoid the problem.
> 
> Signed-off-by: Arnd Bergmann 

Reviewed-by: Laurent Pinchart 

This doesn't conflict with the series I've just sent for the CAL driver,
and can thus be applied first or on top. Hans, can I let you handle this
?

> ---
>  drivers/media/platform/ti-vpe/cal.h | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/media/platform/ti-vpe/cal.h 
> b/drivers/media/platform/ti-vpe/cal.h
> index 4123405ee0cf..20d07311d222 100644
> --- a/drivers/media/platform/ti-vpe/cal.h
> +++ b/drivers/media/platform/ti-vpe/cal.h
> @@ -215,7 +215,7 @@ static inline void cal_write(struct cal_dev *cal, u32 
> offset, u32 val)
>   iowrite32(val, cal->base + offset);
>  }
>  
> -static inline u32 cal_read_field(struct cal_dev *cal, u32 offset, u32 mask)
> +static __always_inline u32 cal_read_field(struct cal_dev *cal, u32 offset, 
> u32 mask)
>  {
>   return FIELD_GET(mask, cal_read(cal, offset));
>  }

-- 
Regards,

Laurent Pinchart


Re: [PATCH 06/12] arm64: dts: zynqmp: Add label for zynqmp_ipi

2020-12-06 Thread Laurent Pinchart
On Mon, Dec 07, 2020 at 12:46:56AM +0200, Laurent Pinchart wrote:
> Hi Michal,
> 
> Thank you for the patch.
> 
> On Wed, Dec 02, 2020 at 03:06:05PM +0100, Michal Simek wrote:
> > Add label which is used by bootloader for adding bootloader specific flag.
> > 
> > Signed-off-by: Michal Simek 
> > ---
> > 
> > U-Boot needs to add u-boot,dm-pre-reloc; property
> 
> I'm not entirely sure what best practice rules are in this area, but
> shouldn't U-Boot locate the node by name instead of label ?

And regardless of what mechanism is used, it should be documented in the
bindings.

> > ---
> >  arch/arm64/boot/dts/xilinx/zynqmp.dtsi | 2 +-
> >  1 file changed, 1 insertion(+), 1 deletion(-)
> > 
> > diff --git a/arch/arm64/boot/dts/xilinx/zynqmp.dtsi 
> > b/arch/arm64/boot/dts/xilinx/zynqmp.dtsi
> > index 4fa820f78d76..8e9b54b5e70c 100644
> > --- a/arch/arm64/boot/dts/xilinx/zynqmp.dtsi
> > +++ b/arch/arm64/boot/dts/xilinx/zynqmp.dtsi
> > @@ -99,7 +99,7 @@ opp03 {
> > };
> > };
> >  
> > -   zynqmp_ipi {
> > +   zynqmp_ipi: zynqmp_ipi {
> >     compatible = "xlnx,zynqmp-ipi-mailbox";
> > interrupt-parent = <>;
> > interrupts = <0 35 4>;

-- 
Regards,

Laurent Pinchart


Re: [PATCH 06/12] arm64: dts: zynqmp: Add label for zynqmp_ipi

2020-12-06 Thread Laurent Pinchart
Hi Michal,

Thank you for the patch.

On Wed, Dec 02, 2020 at 03:06:05PM +0100, Michal Simek wrote:
> Add label which is used by bootloader for adding bootloader specific flag.
> 
> Signed-off-by: Michal Simek 
> ---
> 
> U-Boot needs to add u-boot,dm-pre-reloc; property

I'm not entirely sure what best practice rules are in this area, but
shouldn't U-Boot locate the node by name instead of label ?

> ---
>  arch/arm64/boot/dts/xilinx/zynqmp.dtsi | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/arch/arm64/boot/dts/xilinx/zynqmp.dtsi 
> b/arch/arm64/boot/dts/xilinx/zynqmp.dtsi
> index 4fa820f78d76..8e9b54b5e70c 100644
> --- a/arch/arm64/boot/dts/xilinx/zynqmp.dtsi
> +++ b/arch/arm64/boot/dts/xilinx/zynqmp.dtsi
> @@ -99,7 +99,7 @@ opp03 {
>   };
>   };
>  
> - zynqmp_ipi {
> + zynqmp_ipi: zynqmp_ipi {
>   compatible = "xlnx,zynqmp-ipi-mailbox";
>   interrupt-parent = <>;
>   interrupts = <0 35 4>;

-- 
Regards,

Laurent Pinchart


Re: [PATCH 04/12] arm64: dts: zynqmp: Enable and wire reset controller

2020-12-06 Thread Laurent Pinchart
 power-domains = <_firmware PD_USB_0>;
> + resets = <_reset ZYNQMP_RESET_USB0_CORERESET>,
> +  <_reset ZYNQMP_RESET_USB0_HIBERRESET>,
> +  <_reset ZYNQMP_RESET_USB0_APB>;
> + reset-names = "usb0_crst", "usb0_hibrst", "usb0_apbrst";
>   };
>  
>   usb1: usb@fe30 {
> @@ -743,6 +768,10 @@ usb1: usb@fe30 {
>   reg = <0x0 0xfe30 0x0 0x4>;
>   clock-names = "clk_xin", "clk_ahb";
>   power-domains = <_firmware PD_USB_1>;
> + resets = <_reset ZYNQMP_RESET_USB1_CORERESET>,
> +  <_reset ZYNQMP_RESET_USB1_HIBERRESET>,
> +  <_reset ZYNQMP_RESET_USB1_APB>;
> + reset-names = "usb1_crst", "usb1_hibrst", "usb1_apbrst";
>   };
>  
>   watchdog0: watchdog@fd4d {

-- 
Regards,

Laurent Pinchart


Re: [PATCH 18/18] ipu3: Add driver for dummy INT3472 ACPI device

2020-12-02 Thread Laurent Pinchart
Hi Hans,

On Tue, Dec 01, 2020 at 09:34:58PM +0100, Hans de Goede wrote:
> On 12/1/20 8:21 PM, Andy Shevchenko wrote:
> > On Tue, Dec 01, 2020 at 09:06:38PM +0200, Laurent Pinchart wrote:
> >> On Tue, Dec 01, 2020 at 09:05:23PM +0200, Andy Shevchenko wrote:
> >>> On Tue, Dec 01, 2020 at 08:55:48PM +0200, Laurent Pinchart wrote:
> >>>> On Tue, Dec 01, 2020 at 08:54:17PM +0200, Andy Shevchenko wrote:
> >>>>> On Tue, Dec 01, 2020 at 08:30:03AM +, Dan Scally wrote:
> >>>>>> On 30/11/2020 20:07, Andy Shevchenko wrote:
> >>>
> >>> ...
> >>>
> >>>>>>>> +static struct int3472_sensor_regulator_map 
> >>>>>>>> int3472_sensor_regulator_maps[] = {
> >>>>>>>> +{ "GNDF140809R", 2, miix_510_ov2680 },
> >>>>>>>> +{ "YHCU", 2, surface_go2_ov5693 },
> >>>>>>>> +{ "MSHW0070", 2, surface_book_ov5693 },
> >>>>>>>> +};
> >>>>>>>
> >>>>>>> Hmm... Usual way is to use DMI for that. I'm not sure above will not 
> >>>>>>> give us
> >>>>>>> false positive matches.
> >>>>>>
> >>>>>> I considered DMI too, no problem to switch to that if it's a better 
> >>>>>> choice.
> >>>>>
> >>>>> I prefer DMI as it's a standard way to describe platform quirks in x86 
> >>>>> world.
> >>>>
> >>>> Do you think the Windows driver would use DMI ?
> >>>
> >>> Linux is using DMI for quirks.
> >>>
> >>>> That seems quite
> >>>> unlikely to me, given how they would have to release a new driver binary
> >>>> for every machine. I'm pretty sure that a different mechanism is used to
> >>>> identify camera integration, and I think it would make sense to follow
> >>>> the same approach. That would allow us to avoid large tables of DMI
> >>>> identifiers that would need to be constently updated, potentially making
> >>>> user experience better.
> >>>
> >>> All Surface family can be matched in a way as Apple machines [1].
> >>>
> >>> [1]: https://lkml.org/lkml/2020/4/15/1198
> >>
> >> But not all Surface machines necessarily have the same camera
> >> architecture. My point is that there seems to be identifiers reported in
> >> ACPI for the exact purpose of identifying the camera architecture. If we
> >> used DMI instead, we would have to handle each machine individually.
> > 
> > With help of DMI we may narrow down the search.
> > 
> > But again, we are talking about uncertainity. It may be your way (a lot of
> > platforms that have different settings), or mine (only a few with more or 
> > less
> > standard sets of settings).
> > 
> > DMI is simply standard in Linux (people usually easier can grep for quirks 
> > for
> > a specific platform).
> > 
> > I would rather ask Hans' opinion since he has quite an expertise with DMI 
> > for
> > good and bad.
> 
> So generally there are 2 ways how things like this can go:
> 
> 1) There is sufficient information in the ACPI table and we use data from the
> ACPI tables
> 
> 2) There is unsufficient info in the ACPI tables (or we don't know how to
> get / interpret the data) and we use DMI quirks

And this specific case I believe there is sufficient data in the ACPI
tables, as I don't believe the Windows driver uses DMI quirks, or comes
in the form of machine-specific binaries. We however don't know how to
interpret all the data, but that should hopefully get better over time
(especially as we'll get more data points, with ACPI dumps from machines
whose schematics have leaked).

> Although we do often also use a combination, getting what we can from ACPI,
> combined with a set of defaults for what we cannot get from ACPI
> based on what reference designs use (IOW what most devices seem to have
> copy and pasted). Combined with DMI quirks for when the defaults do not
> work (which is quite often).
> 
> Depending on if "not working because of wrong defaults" has bad side effects,
> another option is also to only allow the driver to load on devices which
> have the necessary info provided through a DMI match.

Right now there shouldn't be bad side effects, but in the future we'll
need to setup a PMIC whose output voltages can be controlled, and
getting it wrong would be very bad. For that I'll definitely vote for
DMI match to start with, but I don't think that precludes using data
from ACPI. We could just prevent the driver from loading if the machine
isn't whitelisted in DMI matches, and still use ACPI data.

> I hope this helps.

-- 
Regards,

Laurent Pinchart


Re: [PATCH 18/18] ipu3: Add driver for dummy INT3472 ACPI device

2020-12-02 Thread Laurent Pinchart
On Wed, Dec 02, 2020 at 01:09:56PM +0200, Sakari Ailus wrote:
> Hi Laurent,
> 
> On Tue, Dec 01, 2020 at 08:37:58PM +0200, Laurent Pinchart wrote:
> > Hi Sakari,
> > 
> > On Tue, Dec 01, 2020 at 05:55:13PM +0200, Sakari Ailus wrote:
> > > On Tue, Dec 01, 2020 at 01:32:32AM +0200, Laurent Pinchart wrote:
> > > > On Mon, Nov 30, 2020 at 10:07:19PM +0200, Andy Shevchenko wrote:
> > > > > On Mon, Nov 30, 2020 at 01:31:29PM +, Daniel Scally wrote:
> > > > > > On platforms where ACPI is designed for use with Windows, resources
> > > > > > that are intended to be consumed by sensor devices are sometimes in
> > > > > > the _CRS of a dummy INT3472 device upon which the sensor depends. 
> > > > > > This
> > > > > > driver binds to the dummy acpi device (which does not represent a
> > > > > 
> > > > > acpi device -> acpi_device
> > > > > 
> > > > > > physical PMIC) and maps them into GPIO lines and regulators for use 
> > > > > > by
> > > > > > the sensor device instead.
> > > > > 
> > > > > ...
> > > > > 
> > > > > > This patch contains the bits of this process that we're least sure 
> > > > > > about.
> > > > > > The sensors in scope for this work are called out as dependent (in 
> > > > > > their
> > > > > > DSDT entry's _DEP) on a device with _HID INT3472. These come in at 
> > > > > > least
> > > > > > 2 kinds; those with an I2cSerialBusV2 entry (which we presume 
> > > > > > therefore
> > > > > > are legitimate tps68470 PMICs that need handling by those drivers - 
> > > > > > work
> > > > > > on that in the future). And those without an I2C device. For those 
> > > > > > without
> > > > > > an I2C device they instead have an array of GPIO pins defined in 
> > > > > > _CRS. So
> > > > > > for example, my Lenovo Miix 510's OVTI2680 sensor is dependent on 
> > > > > > one of
> > > > > > the _latter_ kind of INT3472 devices, with this _CRS:
> > > > > > 
> > > > > > Method (_CRS, 0, NotSerialized)  // _CRS: Current Resource Settings
> > > > > > {
> > > > > > Name (SBUF, ResourceTemplate ()
> > > > > > {
> > > > > > GpioIo (Exclusive, PullDefault, 0x, 0x,
> > > > > > IoRestrictionOutputOnly, "\\_SB.PCI0.GPI0",
> > > > > > 0x00, ResourceConsumer, ,
> > > > > > )
> > > > > > {   // Pin list
> > > > > > 0x0079
> > > > > > }
> > > > > > GpioIo (Exclusive, PullDefault, 0x, 0x,
> > > > > > IoRestrictionOutputOnly, "\\_SB.PCI0.GPI0",
> > > > > > 0x00, ResourceConsumer, ,
> > > > > > )
> > > > > > {   // Pin list
> > > > > > 0x007A
> > > > > > }
> > > > > > GpioIo (Exclusive, PullDefault, 0x, 0x,
> > > > > > IoRestrictionOutputOnly, "\\_SB.PCI0.GPI0",
> > > > > > 0x00, ResourceConsumer, ,
> > > > > > )
> > > > > > {   // Pin list
> > > > > > 0x008F
> > > > > > }
> > > > > > })
> > > > > > Return (SBUF) /* \_SB_.PCI0.PMI1._CRS.SBUF */
> > > > > > }
> > > > > > 
> > > > > > and the same device has a _DSM Method, which returns 32-bit ints 
> > > > > > where
> > > > > > the second lowest byte we noticed to match the pin numbers of the 
> > > > > > GPIO
> > > > > > lines:
> > > > > > 
> > > > > > Method (_DSM, 4, NotSerialized)  // _DSM: Device-Specific Method
> > > > > > {
> > > > > > If ((Arg0 == ToUUID ("79234640-9e10-4fea-a5c1-b5aa8b19756f")))
> > > > > > {
> > > > > > If ((Arg2 == One))
> > > > > > {
> > > > > >

Re: [PATCH 18/18] ipu3: Add driver for dummy INT3472 ACPI device

2020-12-02 Thread Laurent Pinchart
On Wed, Dec 02, 2020 at 11:39:52AM +0200, Andy Shevchenko wrote:
> On Tue, Dec 01, 2020 at 08:59:53PM +, Dan Scally wrote:
> > On 01/12/2020 18:49, Andy Shevchenko wrote:
> 
> ...
> 
> > > Seems we can do this, by locating intel_int3472.c under PDx86 hood and 
> > > dropping
> > > ACPI ID table from TPS68470 MFD driver. The PMIC can be instantiated via
> > > i2c_acpi_new_device() (IIRC the API name).
> > >
> > > And actually it makes more sense since it's not and MFD and should not be 
> > > there.
> > >
> > > (Dan, patch wise the one creates intel_int3472.c followed by another one 
> > > that
> > >  moves ACPI ID from PMIC and introduces its instantiation via I²C board 
> > > info
> > >  structure)
> > 
> > I'm mostly following this, but why would we need an i2c_board_info or
> > i2c_acpi_new_device()? The INT3472 entries that refer to actual tps68470
> > devices do have an I2cSerialBusV2 enumerated in _CRS so in their case
> > there's an i2c device registered with the kernel already.
> 
> Because as we discussed already we can't have two drivers for the same ID
> without a big disruption in the driver(s).
> 
> If you have a single point of enumeration, it will make things much easier
> (refer to the same intel_cht_int33fe driver you mentioned earlier).
> 
> I just realize that the name of int3472 should follow the same pattern, i.e.
> intel_skl_int3472.c

We're mostly focussing on Kaby Lake here though. From what I understand
the ACPI infrastructure for camera support is mostly the same on Sky
Lake, but not identical. I think a single driver should be able to cover
both though.

> > I think we need those things when we get round to handling the
> > VCM/EEPROM that's hidden within the sensor's ACPI entry, but I've not
> > done any work on that yet at all.
> 
> Let's consider this later — one step at a time.

-- 
Regards,

Laurent Pinchart


Re: [PATCH 13/18] ipu3-cio2: Add functionality allowing software_node connections to sensors on platforms designed for Windows

2020-12-01 Thread Laurent Pinchart
Hi Daniel,

On Tue, Dec 01, 2020 at 10:08:25PM +, Dan Scally wrote:
> On 30/11/2020 17:09, Laurent Pinchart wrote:
> > On Mon, Nov 30, 2020 at 01:31:24PM +, Daniel Scally wrote:
> >> Currently on platforms designed for Windows, connections between CIO2 and
> >> sensors are not properly defined in DSDT. This patch extends the ipu3-cio2
> >> driver to compensate by building software_node connections, parsing the
> >> connection properties from the sensor's SSDB buffer.
> >>
> >> Suggested-by: Jordan Hand 
> >> Signed-off-by: Daniel Scally 
> >> ---
> >> Changes since RFC v3:
> >>
> >>- Removed almost all global variables, dynamically allocated
> >>the cio2_bridge structure, plus a bunch of associated changes
> >>like 
> >>- Added a new function to ipu3-cio2-main.c to check for an 
> >>existing fwnode_graph before calling cio2_bridge_init()
> >>- Prefixed cio2_bridge_ to any variables and functions that
> >>lacked it
> >>- Assigned the new fwnode directly to the sensor's ACPI device
> >>fwnode as secondary. This removes the requirement to delay until
> >>the I2C devices are instantiated before ipu3-cio2 can probe, but
> >>it has a side effect, which is that those devices then grab a ref
> >>to the new software_node. This effectively prevents us from
> >>unloading the driver, because we can't free the memory that they
> >>live in whilst the device holds a reference to them. The work
> >>around at the moment is to _not_ unregister the software_nodes
> >>when ipu3-cio2 is unloaded; this becomes a one-time 'patch', that
> >>is simply skipped if the module is reloaded.
> >>- Moved the sensor's SSDB struct to be a member of cio2_sensor
> >>- Replaced ints with unsigned ints where appropriate
> >>- Iterated over all ACPI devices of a matching _HID rather than
> >>just the first to ensure we handle a device with multiple sensors
> >>of the same model.
> >>
> >>  MAINTAINERS   |   1 +
> >>  drivers/media/pci/intel/ipu3/Kconfig  |  18 ++
> >>  drivers/media/pci/intel/ipu3/Makefile |   1 +
> >>  drivers/media/pci/intel/ipu3/cio2-bridge.c| 260 ++
> >>  drivers/media/pci/intel/ipu3/cio2-bridge.h| 108 
> >>  drivers/media/pci/intel/ipu3/ipu3-cio2-main.c |  27 ++
> >>  drivers/media/pci/intel/ipu3/ipu3-cio2.h  |   6 +
> >>  7 files changed, 421 insertions(+)
> >>  create mode 100644 drivers/media/pci/intel/ipu3/cio2-bridge.c
> >>  create mode 100644 drivers/media/pci/intel/ipu3/cio2-bridge.h
> >>
> >> diff --git a/MAINTAINERS b/MAINTAINERS
> >> index 9702b886d6a4..188559a0a610 100644
> >> --- a/MAINTAINERS
> >> +++ b/MAINTAINERS
> >> @@ -8927,6 +8927,7 @@ INTEL IPU3 CSI-2 CIO2 DRIVER
> >>  M:Yong Zhi 
> >>  M:Sakari Ailus 
> >>  M:Bingbu Cao 
> >> +M:Dan Scally 
> >>  R:Tianshu Qiu 
> >>  L:linux-me...@vger.kernel.org
> >>  S:Maintained
> >> diff --git a/drivers/media/pci/intel/ipu3/Kconfig 
> >> b/drivers/media/pci/intel/ipu3/Kconfig
> >> index 82d7f17e6a02..2b3350d042be 100644
> >> --- a/drivers/media/pci/intel/ipu3/Kconfig
> >> +++ b/drivers/media/pci/intel/ipu3/Kconfig
> >> @@ -16,3 +16,21 @@ config VIDEO_IPU3_CIO2
> >>  Say Y or M here if you have a Skylake/Kaby Lake SoC with MIPI CSI-2
> >>  connected camera.
> >>  The module will be called ipu3-cio2.
> >> +
> >> +config CIO2_BRIDGE
> >> +  bool "IPU3 CIO2 Sensors Bridge"
> >> +  depends on VIDEO_IPU3_CIO2
> >> +  help
> >> +This extension provides an API for the ipu3-cio2 driver to create
> >> +connections to cameras that are hidden in SSDB buffer in ACPI. It
> >> +can be used to enable support for cameras in detachable / hybrid
> >> +devices that ship with Windows.
> >> +
> >> +Say Y here if your device is a detachable / hybrid laptop that comes
> >> +with Windows installed by the OEM, for example:
> >> +
> >> +  - Microsoft Surface models (except Surface Pro 3)
> >> +  - The Lenovo Miix line (for example the 510, 520, 710 and 720)
> >> +  - Dell 7285
> >> +
> >> +If in doubt, say N here.
> >> diff --git a

Re: [PATCH 18/18] ipu3: Add driver for dummy INT3472 ACPI device

2020-12-01 Thread Laurent Pinchart
On Tue, Dec 01, 2020 at 09:05:23PM +0200, Andy Shevchenko wrote:
> On Tue, Dec 01, 2020 at 08:55:48PM +0200, Laurent Pinchart wrote:
> > On Tue, Dec 01, 2020 at 08:54:17PM +0200, Andy Shevchenko wrote:
> > > On Tue, Dec 01, 2020 at 08:30:03AM +, Dan Scally wrote:
> > > > On 30/11/2020 20:07, Andy Shevchenko wrote:
> 
> ...
> 
> > > > >> +static struct int3472_sensor_regulator_map 
> > > > >> int3472_sensor_regulator_maps[] = {
> > > > >> +{ "GNDF140809R", 2, miix_510_ov2680 },
> > > > >> +{ "YHCU", 2, surface_go2_ov5693 },
> > > > >> +{ "MSHW0070", 2, surface_book_ov5693 },
> > > > >> +};
> > > > >
> > > > > Hmm... Usual way is to use DMI for that. I'm not sure above will not 
> > > > > give us
> > > > > false positive matches.
> > > >
> > > > I considered DMI too, no problem to switch to that if it's a better 
> > > > choice.
> > > 
> > > I prefer DMI as it's a standard way to describe platform quirks in x86 
> > > world.
> > 
> > Do you think the Windows driver would use DMI ?
> 
> Linux is using DMI for quirks.
> 
> > That seems quite
> > unlikely to me, given how they would have to release a new driver binary
> > for every machine. I'm pretty sure that a different mechanism is used to
> > identify camera integration, and I think it would make sense to follow
> > the same approach. That would allow us to avoid large tables of DMI
> > identifiers that would need to be constently updated, potentially making
> > user experience better.
> 
> All Surface family can be matched in a way as Apple machines [1].
> 
> [1]: https://lkml.org/lkml/2020/4/15/1198

But not all Surface machines necessarily have the same camera
architecture. My point is that there seems to be identifiers reported in
ACPI for the exact purpose of identifying the camera architecture. If we
used DMI instead, we would have to handle each machine individually.

-- 
Regards,

Laurent Pinchart


Re: [PATCH 18/18] ipu3: Add driver for dummy INT3472 ACPI device

2020-12-01 Thread Laurent Pinchart
Hi Andy,

On Tue, Dec 01, 2020 at 08:54:17PM +0200, Andy Shevchenko wrote:
> On Tue, Dec 01, 2020 at 08:30:03AM +, Dan Scally wrote:
> > On 30/11/2020 20:07, Andy Shevchenko wrote:
> 
> ...
> 
> > >> +static struct int3472_sensor_regulator_map 
> > >> int3472_sensor_regulator_maps[] = {
> > >> +{ "GNDF140809R", 2, miix_510_ov2680 },
> > >> +{ "YHCU", 2, surface_go2_ov5693 },
> > >> +{ "MSHW0070", 2, surface_book_ov5693 },
> > >> +};
> > >
> > > Hmm... Usual way is to use DMI for that. I'm not sure above will not give 
> > > us
> > > false positive matches.
> >
> > I considered DMI too, no problem to switch to that if it's a better choice.
> 
> I prefer DMI as it's a standard way to describe platform quirks in x86 world.

Do you think the Windows driver would use DMI ? That seems quite
unlikely to me, given how they would have to release a new driver binary
for every machine. I'm pretty sure that a different mechanism is used to
identify camera integration, and I think it would make sense to follow
the same approach. That would allow us to avoid large tables of DMI
identifiers that would need to be constently updated, potentially making
user experience better.

-- 
Regards,

Laurent Pinchart


Re: [PATCH 18/18] ipu3: Add driver for dummy INT3472 ACPI device

2020-12-01 Thread Laurent Pinchart
Hi Sakari,

On Tue, Dec 01, 2020 at 05:55:13PM +0200, Sakari Ailus wrote:
> On Tue, Dec 01, 2020 at 01:32:32AM +0200, Laurent Pinchart wrote:
> > On Mon, Nov 30, 2020 at 10:07:19PM +0200, Andy Shevchenko wrote:
> > > On Mon, Nov 30, 2020 at 01:31:29PM +, Daniel Scally wrote:
> > > > On platforms where ACPI is designed for use with Windows, resources
> > > > that are intended to be consumed by sensor devices are sometimes in
> > > > the _CRS of a dummy INT3472 device upon which the sensor depends. This
> > > > driver binds to the dummy acpi device (which does not represent a
> > > 
> > > acpi device -> acpi_device
> > > 
> > > > physical PMIC) and maps them into GPIO lines and regulators for use by
> > > > the sensor device instead.
> > > 
> > > ...
> > > 
> > > > This patch contains the bits of this process that we're least sure 
> > > > about.
> > > > The sensors in scope for this work are called out as dependent (in their
> > > > DSDT entry's _DEP) on a device with _HID INT3472. These come in at least
> > > > 2 kinds; those with an I2cSerialBusV2 entry (which we presume therefore
> > > > are legitimate tps68470 PMICs that need handling by those drivers - work
> > > > on that in the future). And those without an I2C device. For those 
> > > > without
> > > > an I2C device they instead have an array of GPIO pins defined in _CRS. 
> > > > So
> > > > for example, my Lenovo Miix 510's OVTI2680 sensor is dependent on one of
> > > > the _latter_ kind of INT3472 devices, with this _CRS:
> > > > 
> > > > Method (_CRS, 0, NotSerialized)  // _CRS: Current Resource Settings
> > > > {
> > > > Name (SBUF, ResourceTemplate ()
> > > > {
> > > > GpioIo (Exclusive, PullDefault, 0x, 0x,
> > > > IoRestrictionOutputOnly, "\\_SB.PCI0.GPI0",
> > > > 0x00, ResourceConsumer, ,
> > > > )
> > > > {   // Pin list
> > > > 0x0079
> > > > }
> > > > GpioIo (Exclusive, PullDefault, 0x, 0x,
> > > > IoRestrictionOutputOnly, "\\_SB.PCI0.GPI0",
> > > > 0x00, ResourceConsumer, ,
> > > > )
> > > > {   // Pin list
> > > > 0x007A
> > > > }
> > > > GpioIo (Exclusive, PullDefault, 0x, 0x,
> > > > IoRestrictionOutputOnly, "\\_SB.PCI0.GPI0",
> > > > 0x00, ResourceConsumer, ,
> > > > )
> > > > {   // Pin list
> > > > 0x008F
> > > > }
> > > > })
> > > > Return (SBUF) /* \_SB_.PCI0.PMI1._CRS.SBUF */
> > > > }
> > > > 
> > > > and the same device has a _DSM Method, which returns 32-bit ints where
> > > > the second lowest byte we noticed to match the pin numbers of the GPIO
> > > > lines:
> > > > 
> > > > Method (_DSM, 4, NotSerialized)  // _DSM: Device-Specific Method
> > > > {
> > > > If ((Arg0 == ToUUID ("79234640-9e10-4fea-a5c1-b5aa8b19756f")))
> > > > {
> > > > If ((Arg2 == One))
> > > > {
> > > > Return (0x03)
> > > > }
> > > > 
> > > > If ((Arg2 == 0x02))
> > > > {
> > > > Return (0x01007900)
> > > > }
> > > > 
> > > > If ((Arg2 == 0x03))
> > > > {
> > > > Return (0x01007A0C)
> > > > }
> > > > 
> > > > If ((Arg2 == 0x04))
> > > > {
> > > > Return (0x01008F01)
> > > > }
> > > > }
> > > > 
> > > > Return (Zero)
> > > > }
> > > > 
> > > > We know that at least some of those pins have to be toggled active for 
> > > > the
> > > > sensor devices to be available in i2c, so the conclusion we came to was
> > > > that those GPIO entries assigned to the INT3472 device actually 
> > > > represent
> > > > GPIOs and regulators to be consumed by the sensors themselves. 

Re: [PATCH 18/18] ipu3: Add driver for dummy INT3472 ACPI device

2020-12-01 Thread Laurent Pinchart
Hi Andy,

On Tue, Dec 01, 2020 at 08:31:39PM +0200, Andy Shevchenko wrote:
> On Mon, Nov 30, 2020 at 11:20:55PM +, Dan Scally wrote:
> > On 30/11/2020 16:17, Jean-Michel Hautbois wrote:
> 
> ...
> 
> > but the ACPI table doesn't define an I2CSerialBusV2 for it. Instead it's
> > rolled under the sensor's entry, there's a second entry in _CRS for the
> > sensor that matches the address of the new device:
> > 
> > 
> > Method (_CRS, 0, NotSerialized)  // _CRS: Current Resource 
> > Settings
> > {
> > Name (SBUF, ResourceTemplate ()
> > {
> > I2cSerialBusV2 (0x0036, ControllerInitiated, 0x00061A80,
> > AddressingMode7Bit, "\\_SB.PCI0.I2C2",
> > 0x00, ResourceConsumer, , Exclusive,
> > )
> > I2cSerialBusV2 (0x000C, ControllerInitiated, 0x00061A80,
> > AddressingMode7Bit, "\\_SB.PCI0.I2C2",
> > 0x00, ResourceConsumer, , Exclusive,
> > )
> > })
> > Return (SBUF) /* \_SB_.PCI0.CAM0._CRS.SBUF */
> > }
> > 
> > So that's another thing we need to work on. At the moment it doesn't
> > exist as far as the kernel is concerned.
> 
> Maybe something along i2c-multi-instantiate can help here (maybe not).

It's two different devices really. That's also one of the "annoyances"
related to this platform. The INT* HID for the camera sensor actually
refers to a camera module, with VCM, EEPROM, ... On Chrome OS devices,
the same HID refers to the camera sensor only. *sigh* :-(

> P.S. Dan, can you drop unrelated text when replying?

I find a full quote actually useful, as it saves me from having to dig
up original e-mails to read missing parts :-) It's a matter of
preference I suppose.

-- 
Regards,

Laurent Pinchart


Re: [PATCH 18/18] ipu3: Add driver for dummy INT3472 ACPI device

2020-12-01 Thread Laurent Pinchart
Hi Sakari,

On Tue, Dec 01, 2020 at 02:32:44PM +0200, Sakari Ailus wrote:
> On Tue, Dec 01, 2020 at 08:08:26AM +, Dan Scally wrote:
> > On 01/12/2020 06:44, Sakari Ailus wrote:
> > > On Mon, Nov 30, 2020 at 11:06:03PM +, Dan Scally wrote:
> > >> On 30/11/2020 20:52, Sakari Ailus wrote:
> > >>>> +static const struct acpi_device_id int3472_device_id[] = {
> > >>>> +  { "INT3472", 0 },
> > >>>
> > >>> The INT3472 _HID is really allocated for the tps68470 PMIC chip. It may 
> > >>> not
> > >>> be used by other drivers; people will want to build kernels where both 
> > >>> of
> > >>> these ACPI table layouts are functional.
> > >>>
> > >>> Instead, I propose, that you add this as an option to the tps68470 
> > >>> driver
> > >>> that figures out whether the ACPI device for the tps68470 device 
> > >>> actually
> > >>> describes something else, in a similar fashion you do with the 
> > >>> cio2-bridge
> > >>> driver. I think it may need a separate Kconfig option albeit this and
> > >>> cio2-bridge cannot be used separately.
> > >>
> > >> It actually occurs to me that that may not work (I know I called that
> > >> out as an option we considered, but that was a while ago actually). The
> > >> reason I wasn't worried about the existing tps68470 driver binding to
> > >> these devices is that it's an i2c driver, and these dummy devices don't
> > >> have an I2cSerialBusV2, so no I2C device is created by them the kernel.
> > >>
> > >> Won't that mean the tps68470 driver won't ever be probed for these 
> > >> devices?
> > >
> > > Oops. I missed this indeed was not an I²C driver. So please ignore the
> > > comment.
> > >
> > > So I guess this wouldn't be an actual problem. I'd still like to test this
> > > on a system with tps68470, as the rest of the set.
> >
> > On my Go2, it .probes() for the actual tps68740 (that machine has both
> > types of INT3472 device) but fails with EINVAL when it can't find the
> > CLDB buffer that these discrete type devices have. My understanding is
> > that means it's free for the actual tps68470 driver to grab the device;
> > although that's not happening because I had to blacklist that driver or
> > it stops the machine from booting at the moment - haven't gotten round
> > to investigating yet.
> 
> Oh, then the problem is actually there. If it probes the tps68470 driver on
> the systems with Windows ACPI tables, then it should be that driver which
> works with the Windows ACPI tables, too.
> 
> Checking for random objects such as CLDB in multiple drivers and returning
> an error based on them being there or not wouldn't be exactly neat.
> Although I'm not sure thare are options that are obviosly pretty here. I
> wouldn't two separate drivers checking for e.g. CLDB (tps68470 + this one).
> 
> The tps68470 driver is an MFD driver that instantiates a number of platform
> devices. Alternatively, if you make this one a platform device, you can, in
> case the CLDB (or whatever object) is present, in the tps68470 driver
> instantiate a device for this driver instead of the rest.
> 
> So I'd think what matters is that both drivers can be selected at the same
> time but the user does not need to manually select them. Both ways could
> work I guess?

Let's make it simpler instead of creating lots of devices. Here's what
I've proposed in a different e-mail in this thread.

> Given that INT3472 means Intel camera power management device (that's
> more or less the wording in Windows, I can double-check), would the
> following make sense ?
> 
> A top-level module named intel-camera-pmic (or int3472, or ...) would
> register two drivers, a platform driver and an I2C driver, to
> accommodate for both cases ("discrete PMIC" that doesn't have an
> I2cSerialBusV2, and TPS64870 or uP6641Q that are I2C devices). The probe
> function would perform the following:
> 
> - If there's no CLDB, then the device uses the Chrome OS "ACPI
>   bindings", and refers to a TPS64870. The code that exists in the
>   kernel today (registering GPIOs, and registering an OpRegion to
>   communicate with the power management code in the DSDT) would be
>   activated.
> 
> - If there's a CLDB, then the device type would be retrieved from it:
> 
>   - If the device is a "discrete PMIC", the driver would register clocks
> and regulators controlled by GPIOs, and create 

Re: [PATCH 18/18] ipu3: Add driver for dummy INT3472 ACPI device

2020-11-30 Thread Laurent Pinchart
ver source code, but definitely somewhere else than in the
commit message.

> > After much internal debate I decided to write this as a standalone
> > acpi_driver. Alternative options we considered:
> > 
> > 1. Squash all this into the cio2-bridge code, which I did originally write
> > but decided I didn't like.
> > 2. Extend the existing tps68470 mfd driver...they share an ACPI ID so this
> > kinda makes sense, but ultimately given there is no actual physical
> > tps68470 in the scenario this patch handles I decided I didn't like this
> > either.
> 
> Looking to this I think the best is to create a module that can be consumed 
> by tps68470 and separately.
> So, something near to it rather than under ipu3 hood.
> 
> You may use same ID's in both drivers (in PMIC less case it can be simple
> platform and thus they won't conflict), but both of them should provide GPIO
> resources for consumption.
> 
> So, something like
> 
>  tps68470.h with API to consume
>  split tps68470 to -core, -i2c parts
>  add int3472, which will serve for above and be standalone platform driver
>  update cio2-bridge accordingly
> 
> Would it be feasible?

Given that INT3472 means Intel camera power management device (that's
more or less the wording in Windows, I can double-check), would the
following make sense ?

A top-level module named intel-camera-pmic (or int3472, or ...) would
register two drivers, a platform driver and an I2C driver, to
accommodate for both cases ("discrete PMIC" that doesn't have an
I2cSerialBusV2, and TPS64870 or uP6641Q that are I2C devices). The probe
function would perform the following:

- If there's no CLDB, then the device uses the Chrome OS "ACPI
  bindings", and refers to a TPS64870. The code that exists in the
  kernel today (registering GPIOs, and registering an OpRegion to
  communicate with the power management code in the DSDT) would be
  activated.

- If there's a CLDB, then the device type would be retrieved from it:

  - If the device is a "discrete PMIC", the driver would register clocks
and regulators controlled by GPIOs, and create clock, regulator and
GPIO lookup entries for the sensor device that references the PMIC.

  - If the device is a TPS64870, the code that exists in the kernel
today to register GPIOs would be activated, and new code would need
to be written to register regulators and clocks.

  - If the device is a uP6641Q, a new driver will need to be written (I
don't know on which devices this PMIC is used, so this can probably
be deferred).

We can split this in multiple files and/or modules.

> ...
> 
> > +   table_entry = (struct gpiod_lookup)GPIO_LOOKUP_IDX(acpi_dev_name(adev),
> > +  
> > ares->data.gpio.pin_table[0],
> > +  func, 0, 
> > GPIO_ACTIVE_HIGH);
> 
> You won't need this if you have regular INT3472 platform driver.
> Simple call there _DSM to map resources to the type and use devm_gpiod_get on
> consumer behalf. Thus, previous patch is not needed.

How does the consumer (the camera sensor) retrieve the GPIO though ? The
_DSM is in the PMIC device object, while the real consumer is the camera
sensor.

> ...
> 
> > +   case 0x01: /* Power regulators (we think) */
> > +   case 0x0c:
> > +   case 0x0b: /* Power regulators, but to a device separate to sensor */
> > +   case 0x0d: /* Indicator LEDs */
> 
> 
> Give names to those constants.
> 
>   #define INT3472_GPIO_TYPE_RESET 0x00
>   ...
> 
> 
> > +static struct acpi_driver int3472_driver = {
> 
> No acpi_driver! Use platform_driver instead with plenty of examples all over
> the kernel.
> 
> > +   .name = "int3472",
> > +   .ids = int3472_device_id,
> > +   .ops = {
> > +   .add = int3472_add,
> > +   .remove = int3472_remove,
> > +   },
> 
> > +   .owner = THIS_MODULE,
> 
> No need
> 
> > +};
> 
> ...
> 
> > +const guid_t int3472_gpio_guid = GUID_INIT(0x79234640, 0x9e10, 0x4fea,
> > +0xa5, 0xc1, 0xb5, 0xaa, 0x8b,
> > +0x19, 0x75, 0x6f);
> > +
> > +const guid_t cio2_sensor_module_guid = GUID_INIT(0x822ace8f, 0x2814, 
> > 0x4174,
> > +0xa5, 0x6b, 0x5f, 0x02, 0x9f,
> > +0xe0, 0x79, 0xee);
> 
> Use more or less standard pattern for these, like
> 
> /* 79234640-9e10-4fea-a5c1b5aa8b19756f */
> const guid_t int3472_gpio_guid =
>   GUID_INIT(0x79234640, 0x9e10, 0x4fea,
> 0xa5, 0xc1, 0xb5, 0xaa, 0x8b, 0x19, 0x75, 0x6f);
> 
> ...
> 
> > +static struct regulator_consumer_supply miix_510_ov2680[] = {
> > +   { "i2c-OVTI2680:00", "avdd" },
> > +   { "i2c-OVTI2680:00", "dovdd" },
> > +};
> 
> Can we use acpi_dev_first_match_dev() to get instance name out of their HIDs?
> 
> > +static struct regulator_consumer_supply surface_go2_ov5693[] = {
> > +   { "i2c-INT33BE:00", "avdd" },
> > +   { "i2c-INT33BE:00", "dovdd" },
> > +};
> > +
> > +static struct regulator_consumer_supply surface_book_ov5693[] = {
> > +   { "i2c-INT33BE:00", "avdd" },
> > +   { "i2c-INT33BE:00", "dovdd" },
> > +};
> 
> Ditto.
> 
> ...
> 
> > +static struct int3472_sensor_regulator_map int3472_sensor_regulator_maps[] 
> > = {
> > +   { "GNDF140809R", 2, miix_510_ov2680 },
> > +   { "YHCU", 2, surface_go2_ov5693 },
> > +   { "MSHW0070", 2, surface_book_ov5693 },
> > +};
> 
> Hmm... Usual way is to use DMI for that. I'm not sure above will not give us
> false positive matches.

-- 
Regards,

Laurent Pinchart


Re: [PATCH 18/18] ipu3: Add driver for dummy INT3472 ACPI device

2020-11-30 Thread Laurent Pinchart
n;
> >> +  /*
> >> +   * control logic type
> >> +   * 0: UNKNOWN
> >> +   * 1: DISCRETE(CRD-D)
> >> +   * 2: PMIC TPS68470
> >> +   * 3: PMIC uP6641
> >> +   */
> >> +  u8 control_logic_type;
> >> +  u8 control_logic_id;
> >> +  u8 sensor_card_sku;
> >> +  u8 reserved[28];
> >> +};
> >> +
> >> +struct int3472_device {
> >> +  struct acpi_device *adev;
> >> +  struct acpi_device *sensor;
> >> +
> >> +  unsigned int n_gpios; /* how many GPIOs have we seen */
> >> +
> >> +  unsigned int n_regulators;
> >> +  struct list_head regulators;
> >> +
> >> +  unsigned int n_sensor_gpios; /* how many have we mapped to sensor */
> >> +  struct gpiod_lookup_table gpios;
> >> +};
> >> +
> >> +struct int3472_gpio_regulator {
> >> +  char regulator_name[GPIO_REGULATOR_NAME_LENGTH];
> >> +  char supply_name[GPIO_REGULATOR_SUPPLY_NAME_LENGTH];
> >> +  struct gpio_desc *gpio;
> >> +  struct regulator_dev *rdev;
> >> +  struct regulator_desc rdesc;
> >> +  struct list_head list;
> >> +};
> >> +
> >> +struct int3472_sensor_regulator_map {
> >> +  char *sensor_module_name;
> >> +  unsigned int n_supplies;
> >> +  struct regulator_consumer_supply *supplies;
> >> +};
> >> +
> >> +/*
> >> + * Here follows platform specific mapping information that we can pass to
> >> + * regulator_init_data when we register our regulators. They're just 
> >> mapped
> >> + * via index, I.E. the first regulator pin that the code finds for the
> >> + * i2c-OVTI2680:00 device is avdd, the second is dovdd and so on.
> >> + */
> >> +
> >> +static struct regulator_consumer_supply miix_510_ov2680[] = {
> >> +  { "i2c-OVTI2680:00", "avdd" },
> >> +  { "i2c-OVTI2680:00", "dovdd" },
> >> +};
> >> +
> >> +static struct regulator_consumer_supply surface_go2_ov5693[] = {
> >> +  { "i2c-INT33BE:00", "avdd" },
> >> +  { "i2c-INT33BE:00", "dovdd" },
> >> +};
> >> +
> >> +static struct regulator_consumer_supply surface_book_ov5693[] = {
> >> +  { "i2c-INT33BE:00", "avdd" },
> >> +  { "i2c-INT33BE:00", "dovdd" },
> >> +};
> >> +
> >> +static struct int3472_sensor_regulator_map 
> >> int3472_sensor_regulator_maps[] = {
> >> +  { "GNDF140809R", 2, miix_510_ov2680 },
> >> +  { "YHCU", 2, surface_go2_ov5693 },
> >> +  { "MSHW0070", 2, surface_book_ov5693 },
> >> +};

-- 
Regards,

Laurent Pinchart


Re: [PATCH 02/18] property: Add support for calling fwnode_graph_get_endpoint_by_id() for fwnode->secondary

2020-11-30 Thread Laurent Pinchart
Hi Andy,

On Mon, Nov 30, 2020 at 07:53:19PM +0200, Andy Shevchenko wrote:
> On Mon, Nov 30, 2020 at 07:28:57PM +0200, Laurent Pinchart wrote:
> > On Mon, Nov 30, 2020 at 07:29:00PM +0200, Andy Shevchenko wrote:
> > > On Mon, Nov 30, 2020 at 01:31:13PM +, Daniel Scally wrote:
> 
> ...
> 
> > > > +   if (!best_ep && fwnode && !IS_ERR_OR_NULL(fwnode->secondary))
> > > > +   return 
> > > > fwnode_graph_get_endpoint_by_id(fwnode->secondary, port,
> > > > +  endpoint, flags);
> > > 
> > > > return best_ep;
> > > 
> > > Can we, please, do
> > > 
> > >   if (best_ep)
> > >   return best_ep;
> > > 
> > >   if (fwnode && !IS_ERR_OR_NULL(fwnode->secondary))
> > >   return fwnode_graph_get_endpoint_by_id(fwnode->secondary, port,
> > >  endpoint, flags);
> > > 
> > >   return NULL;
> > > 
> > > ?
> > > 
> > > This 'if (fwnode && !IS_ERR_OR_NULL(fwnode->secondary))' becomes kinda
> > > idiomatic to the cases when we need to proceed primary followed by the
> > > secondary in cases where it's not already done.
> > 
> > We could also move the !fwnode check to the beginning of the function.
> 
> It's already there (1). What did I miss?

It is, but as we need an explicitly check at the end, it feels cleaner
to move it to the beginning. No big deal though.

> 1) via fwnode_graph_get_next_endpoint() -> fwnode_call_ptr_op()

-- 
Regards,

Laurent Pinchart


Re: [PATCH 14/18] acpi: utils: Add function to fetch dependent acpi_devices

2020-11-30 Thread Laurent Pinchart
Hi Andy,

On Mon, Nov 30, 2020 at 08:23:54PM +0200, Andy Shevchenko wrote:
> On Mon, Nov 30, 2020 at 01:31:25PM +, Daniel Scally wrote:
> > ACPI devices declare themselves dependent on other devices via the _DEP
> > buffer. Fetching the dependee from dependent is a matter of parsing
> > _DEP, but currently there's no method to fetch dependent from dependee.
> > Add one, so we can parse sensors dependent on a PMIC from the PMIC's
> > acpi_driver.
> 
> Do I understand correctly that it's an existing table provided by firmware 
> that
> (ab)uses _DEP in such way? Note, the specification doesn't tell we may use it
> in this way, OTOH I don't remember if it strictly forbids such use.

The ACPI "bindings" (I come from the DT world, is there a standard term
to describe this in ACPI ?) for the camera in Windows-based Kaby Lake
machines could be used as textbook examples of how to abuse ACPI, in
many different ways :-) I'm sure that applies to ACPI in general
though...

Depending on the device, camera sensors are controlled by a PMIC that
provides regulators, clocks and GPIOs (for the reset and power down
signals), or directly by GPIOs that control discrete regulators and
sensor signals. In the first case an INT3472 device models the
regulator, which can be a TI TPS68470 or a uPI Semi uP6641Q (two
completely different devices with a single HID...). The device model is
specified in the CLDB, a custom data table for INT3472.

In the latter case, Intel has created ACPI bindings for a "discrete
PMIC". It uses an ACPI device object with HID set to INT3472 as well,
also with a CLDB whose type field indicate the PMIC is "discrete". The
ACPI device is only used to reference up to 4 GPIOs (provided by the
Kaby Lake GPIO controller, the LPSS) in the _CRS. There's also a _DSM
that reports, for each GPIO, its function. All this information should
have been stored in the camera sensor ACPI device object, but that would
have been too simple...

In both cases, the PMIC device object is referenced by the _DEP data. We
need to access it to dig up the GPIOs, look up their type, and register
fixed regulators, supply mappings and GPIO mappings for the sensor.

> So, please elaborate in the commit message why you need this and pint out to
> the 6.5.8 "_DEP (Operation Region Dependencies)" which clearly says about
> OpRegions and that part already supported by ACPI in the Linux, if I'm not
> mistaken, need to refresh my memory.
> 
> ...
> 
> > +   handle = adev->handle;
> > +
> > +   if (!acpi_has_method(handle, "_DEP"))
> > +   return 0;
> > +
> > +   status = acpi_evaluate_reference(handle, "_DEP", NULL, _handles);
> > +   if (ACPI_FAILURE(status))
> > +   return 0;
> > +
> > +   for (i = 0; i < dep_handles.count; i++) {
> > +   struct acpi_device_info *info;
> > +
> > +   status = acpi_get_object_info(dep_handles.handles[i], );
> > +   if (ACPI_FAILURE(status))
> > +   continue;
> > +
> > +   if (info->valid & ACPI_VALID_HID) {
> > +   ret = acpi_bus_get_device(dep_handles.handles[i], 
> > );
> > +   if (ret || !candidate) {
> > +   kfree(info);
> > +   continue;
> > +   }
> > +
> > +   if (candidate == dependee) {
> > +   acpi_dev_put(candidate);
> > +   kfree(info);
> > +   return 1;
> > +   }
> > +
> > +   kfree(info);
> > +   }
> > +   }
> 
> Can you utilize (by moving to here and export for ACPI layer the
> acpi_lpss_dep()?

-- 
Regards,

Laurent Pinchart


Re: [PATCH 02/18] property: Add support for calling fwnode_graph_get_endpoint_by_id() for fwnode->secondary

2020-11-30 Thread Laurent Pinchart
On Mon, Nov 30, 2020 at 07:29:00PM +0200, Andy Shevchenko wrote:
> On Mon, Nov 30, 2020 at 01:31:13PM +, Daniel Scally wrote:
> > This function is used to find fwnode endpoints against a device. In
> > some instances those endpoints are software nodes which are children of
> > fwnode->secondary. Add support to fwnode_graph_get_endpoint_by_id() to
> > find those endpoints by recursively calling itself passing the ptr to
> > fwnode->secondary in the event no endpoint is found for the primary.
> 
> One nit below, after addressing:
> Reviewed-by: Andy Shevchenko 
> 
> ...
> 
> > +   if (!best_ep && fwnode && !IS_ERR_OR_NULL(fwnode->secondary))
> > +   return fwnode_graph_get_endpoint_by_id(fwnode->secondary, port,
> > +  endpoint, flags);
> 
> > return best_ep;
> 
> Can we, please, do
> 
>   if (best_ep)
>   return best_ep;
> 
>   if (fwnode && !IS_ERR_OR_NULL(fwnode->secondary))
>   return fwnode_graph_get_endpoint_by_id(fwnode->secondary, port,
>  endpoint, flags);
> 
>   return NULL;
> 
> ?
> 
> This 'if (fwnode && !IS_ERR_OR_NULL(fwnode->secondary))' becomes kinda
> idiomatic to the cases when we need to proceed primary followed by the
> secondary in cases where it's not already done.

We could also move the !fwnode check to the beginning of the function.

> >  }
> >  EXPORT_SYMBOL_GPL(fwnode_graph_get_endpoint_by_id);

-- 
Regards,

Laurent Pinchart


Re: [PATCH 18/18] ipu3: Add driver for dummy INT3472 ACPI device

2020-11-30 Thread Laurent Pinchart
Hello,

On Mon, Nov 30, 2020 at 04:29:04PM +, Kieran Bingham wrote:
> On 30/11/2020 13:31, Daniel Scally wrote:
> > On platforms where ACPI is designed for use with Windows, resources
> > that are intended to be consumed by sensor devices are sometimes in
> > the _CRS of a dummy INT3472 device upon which the sensor depends. This
> > driver binds to the dummy acpi device (which does not represent a
> > physical PMIC) and maps them into GPIO lines and regulators for use by
> > the sensor device instead.
> > 
> > Suggested-by: Laurent Pinchart 
> > Signed-off-by: Daniel Scally 
> > ---
> > Changes since RFC v3:
> > 
> > - Patch introduced
> > 
> > This patch contains the bits of this process that we're least sure about.
> > The sensors in scope for this work are called out as dependent (in their
> > DSDT entry's _DEP) on a device with _HID INT3472. These come in at least
> > 2 kinds; those with an I2cSerialBusV2 entry (which we presume therefore
> > are legitimate tps68470 PMICs that need handling by those drivers - work
> > on that in the future). And those without an I2C device. For those without
> > an I2C device they instead have an array of GPIO pins defined in _CRS.

Those are called "discrete regulators", and can also be identified by
the type reported in the CLDB. They're not regulators, just ACPI device
objects that group a set of GPIOs and a referenced from the consumers of
those GPIOs. I'll refrain here from sharing my opinion on the ACPI
design...

> > So
> > for example, my Lenovo Miix 510's OVTI2680 sensor is dependent on one of
> > the _latter_ kind of INT3472 devices, with this _CRS:
> > 
> > Method (_CRS, 0, NotSerialized)  // _CRS: Current Resource Settings
> > {
> > Name (SBUF, ResourceTemplate ()
> > {
> > GpioIo (Exclusive, PullDefault, 0x, 0x,
> > IoRestrictionOutputOnly, "\\_SB.PCI0.GPI0",
> > 0x00, ResourceConsumer, ,
> > )
> > {   // Pin list
> > 0x0079
> > }
> > GpioIo (Exclusive, PullDefault, 0x, 0x,
> > IoRestrictionOutputOnly, "\\_SB.PCI0.GPI0",
> > 0x00, ResourceConsumer, ,
> > )
> > {   // Pin list
> > 0x007A
> > }
> > GpioIo (Exclusive, PullDefault, 0x, 0x,
> > IoRestrictionOutputOnly, "\\_SB.PCI0.GPI0",
> > 0x00, ResourceConsumer, ,
> > )
> > {   // Pin list
> > 0x008F
> > }
> > })
> > Return (SBUF) /* \_SB_.PCI0.PMI1._CRS.SBUF */
> > }
> > 
> > and the same device has a _DSM Method, which returns 32-bit ints where
> > the second lowest byte we noticed to match the pin numbers of the GPIO
> > lines:
> > 
> > Method (_DSM, 4, NotSerialized)  // _DSM: Device-Specific Method
> > {
> > If ((Arg0 == ToUUID ("79234640-9e10-4fea-a5c1-b5aa8b19756f")))
> > {
> > If ((Arg2 == One))
> > {
> > Return (0x03)
> > }
> > 
> > If ((Arg2 == 0x02))
> > {
> > Return (0x01007900)
> > }
> > 
> > If ((Arg2 == 0x03))
> > {
> > Return (0x01007A0C)
> > }
> > 
> > If ((Arg2 == 0x04))
> > {
> > Return (0x01008F01)
> > }
> > }
> > 
> > Return (Zero)
> > }
> > 
> > We know that at least some of those pins have to be toggled active for the
> > sensor devices to be available in i2c, so the conclusion we came to was
> > that those GPIO entries assigned to the INT3472 device actually represent
> > GPIOs and regulators to be consumed by the sensors themselves. Tsuchiya
> > noticed that the lowest byte in the return values of the _DSM method
> > seemed to represent the type or function of the GPIO line, and we
> > confirmed that by testing on each surface device that GPIO lines where the
> > low byte in the _DSM entry for that pin was 0x0d controlled the privacy
> > LED of the cameras.
> > 
> > We're guessing as to the exact meaning of the function byte, but I
> > conclude they're something like this:
> > 
> > 0x00 - probably a reset GPIO
> > 0x01 - regulator for the sensor

I think 0x01 is probably a power down GPIO.

> > 0x0c - regulator for the sensor
> > 0x0b - regulator again, but for a VCM or EEPROM
> > 0x0d - pr

Re: [PATCH 15/18] i2c: i2c-core-acpi: Add i2c_acpi_dev_name()

2020-11-30 Thread Laurent Pinchart
Hi Daniel,

Thank you for the patch.

On Mon, Nov 30, 2020 at 01:31:26PM +, Daniel Scally wrote:
> Some places in the kernel allow users to map resources to a device
> using device name (for example, gpiod_lookup_table). Currently
> this involves waiting for the i2c_client to have been registered so we
> can use dev_name(>dev). Adding this function means that we can
> achieve the same thing without having to wait to the i2c device.
> 
> Signed-off-by: Daniel Scally 
> ---
> Changes since RFC v3:
> 
>   - Patch introduced
> 
>  drivers/i2c/i2c-core-acpi.c | 14 ++
>  include/linux/i2c.h |  5 +
>  2 files changed, 19 insertions(+)
> 
> diff --git a/drivers/i2c/i2c-core-acpi.c b/drivers/i2c/i2c-core-acpi.c
> index 37c510d9347a..d3a653eac79e 100644
> --- a/drivers/i2c/i2c-core-acpi.c
> +++ b/drivers/i2c/i2c-core-acpi.c
> @@ -497,6 +497,20 @@ struct i2c_client *i2c_acpi_new_device(struct device 
> *dev, int index,
>  }
>  EXPORT_SYMBOL_GPL(i2c_acpi_new_device);
>  
> +/**
> + * i2c_acpi_dev_name - Construct i2c device name for devs sourced from ACPI
> + * @adev: ACPI device to construct the name for
> + *
> + * Prefixes "i2c-" to the ACPI device name, for use in i2c_dev_set_name() and
> + * also anywhere else in the kernel that needs to refer to an i2c device by
> + * name but before they have been instantiated.

The documentation should state that the caller must free the return
value.

> + */
> +char *i2c_acpi_dev_name(struct acpi_device *adev)
> +{
> + return kasprintf(GFP_KERNEL, "i2c-%s", acpi_dev_name(adev));
> +}
> +EXPORT_SYMBOL_GPL(i2c_acpi_dev_name);
> +
>  #ifdef CONFIG_ACPI_I2C_OPREGION
>  static int acpi_gsb_i2c_read_bytes(struct i2c_client *client,
>   u8 cmd, u8 *data, u8 data_len)
> diff --git a/include/linux/i2c.h b/include/linux/i2c.h
> index 56622658b215..ab0e505b2ca6 100644
> --- a/include/linux/i2c.h
> +++ b/include/linux/i2c.h
> @@ -995,6 +995,7 @@ bool i2c_acpi_get_i2c_resource(struct acpi_resource *ares,
>  u32 i2c_acpi_find_bus_speed(struct device *dev);
>  struct i2c_client *i2c_acpi_new_device(struct device *dev, int index,
>  struct i2c_board_info *info);
> +char *i2c_acpi_dev_name(struct acpi_device *adev);
>  struct i2c_adapter *i2c_acpi_find_adapter_by_handle(acpi_handle handle);
>  #else
>  static inline bool i2c_acpi_get_i2c_resource(struct acpi_resource *ares,
> @@ -1011,6 +1012,10 @@ static inline struct i2c_client 
> *i2c_acpi_new_device(struct device *dev,
>  {
>   return ERR_PTR(-ENODEV);
>  }
> +static inline char *i2c_acpi_dev_name(struct acpi_device *adev)
> +{
> + return NULL;
> +}
>  static inline struct i2c_adapter 
> *i2c_acpi_find_adapter_by_handle(acpi_handle handle)
>  {
>   return NULL;

-- 
Regards,

Laurent Pinchart


Re: [PATCH 16/18] i2c: i2c-core-base: Use the new i2c_acpi_dev_name() in i2c_set_dev_name()

2020-11-30 Thread Laurent Pinchart
Hi Daniel,

Thank you for the patch.

On Mon, Nov 30, 2020 at 01:31:27PM +, Daniel Scally wrote:
> From: Dan Scally 
> 
> To make sure the new i2c_acpi_dev_name() always reflects the name of i2c
> devices sourced from ACPI, use it in i2c_set_dev_name().
> 
> Signed-off-by: Dan Scally 

I'd squash this with 15/18, which would make it clear there's a memory
leak :-)

> ---
> Changes since RFC v3:
> 
>   - Patch introduced
> 
>  drivers/i2c/i2c-core-base.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/i2c/i2c-core-base.c b/drivers/i2c/i2c-core-base.c
> index 573b5da145d1..a6d4ceb01077 100644
> --- a/drivers/i2c/i2c-core-base.c
> +++ b/drivers/i2c/i2c-core-base.c
> @@ -814,7 +814,7 @@ static void i2c_dev_set_name(struct i2c_adapter *adap,
>   }
>  
>   if (adev) {
> - dev_set_name(>dev, "i2c-%s", acpi_dev_name(adev));
> + dev_set_name(>dev, i2c_acpi_dev_name(adev));
>   return;
>   }
>  

-- 
Regards,

Laurent Pinchart


Re: [PATCH 13/18] ipu3-cio2: Add functionality allowing software_node connections to sensors on platforms designed for Windows

2020-11-30 Thread Laurent Pinchart
sensorcalibfileidxInMBZ[3];
> + u8 romtype;
> + u8 vcmtype;
> + u8 platforminfo;
> + u8 platformsubinfo;
> + u8 flash;
> + u8 privacyled;
> + u8 degree;
> + u8 mipilinkdefined;
> + u32 mclkspeed;
> + u8 controllogicid;
> + u8 reserved1[3];
> + u8 mclkport;
> + u8 reserved2[13];
> +} __packed__;
> +
> +struct cio2_property_names {
> + char clock_frequency[16];
> + char rotation[9];
> + char bus_type[9];
> + char data_lanes[11];
> + char remote_endpoint[16];
> +};
> +
> +struct cio2_node_names {
> + char port[6];
> + char endpoint[10];
> + char remote_port[6];
> +};
> +
> +struct cio2_sensor {
> + char name[ACPI_ID_LEN];
> + struct acpi_device *adev;
> +
> + struct software_node swnodes[6];
> + struct cio2_node_names node_names;
> +
> + u32 data_lanes[4];
> + struct cio2_sensor_ssdb ssdb;
> + struct cio2_property_names prop_names;
> + struct property_entry ep_properties[4];
> + struct property_entry dev_properties[3];
> + struct property_entry cio2_properties[3];
> + struct software_node_ref_args local_ref[1];
> + struct software_node_ref_args remote_ref[1];
> +};
> +
> +struct cio2_bridge {
> + struct pci_dev *cio2;
> + char cio2_node_name[ACPI_ID_LEN];
> + struct software_node cio2_hid_node;
> + unsigned int n_sensors;
> + struct cio2_sensor sensors[CIO2_NUM_PORTS];
> +};
> +
> +#endif
> diff --git a/drivers/media/pci/intel/ipu3/ipu3-cio2-main.c 
> b/drivers/media/pci/intel/ipu3/ipu3-cio2-main.c
> index 36e354ecf71e..0d69b593e9f0 100644
> --- a/drivers/media/pci/intel/ipu3/ipu3-cio2-main.c
> +++ b/drivers/media/pci/intel/ipu3/ipu3-cio2-main.c
> @@ -1702,6 +1702,22 @@ static void cio2_queues_exit(struct cio2_device *cio2)
>   cio2_queue_exit(cio2, >queue[i]);
>  }
>  
> +static bool cio2_check_fwnode_graph(struct fwnode_handle *fwnode)
> +{
> + struct fwnode_handle *endpoint;
> +
> + if (IS_ERR_OR_NULL(fwnode))
> + return false;
> +
> + endpoint = fwnode_graph_get_next_endpoint(fwnode, NULL);
> + if (endpoint) {
> + fwnode_handle_put(endpoint);
> + return true;
> + }
> +
> + return cio2_check_fwnode_graph(fwnode->secondary);

If we have a fwnode->secondary and this check fails there's something
seriously wrong, I wonder if we should print an error message.

Overall this is nice. I think the next version will get my ack :-)

> +}
> +
>  / PCI interface /
>  
>  static int cio2_pci_probe(struct pci_dev *pci_dev,
> @@ -1715,6 +1731,17 @@ static int cio2_pci_probe(struct pci_dev *pci_dev,
>   return -ENOMEM;
>   cio2->pci_dev = pci_dev;
>  
> + /*
> +  * On some platforms no connections to sensors are defined in firmware,
> +  * if the device has no endpoints then we can try to build those as
> +  * software_nodes parsed from SSDB.
> +  */
> + if (!cio2_check_fwnode_graph(dev_fwnode(_dev->dev))) {
> + r = cio2_bridge_init(pci_dev);
> + if (r)
> + return r;
> + }
> +
>   r = pcim_enable_device(pci_dev);
>   if (r) {
>   dev_err(_dev->dev, "failed to enable device (%d)\n", r);
> diff --git a/drivers/media/pci/intel/ipu3/ipu3-cio2.h 
> b/drivers/media/pci/intel/ipu3/ipu3-cio2.h
> index ccf0b85ae36f..520a27c9cdad 100644
> --- a/drivers/media/pci/intel/ipu3/ipu3-cio2.h
> +++ b/drivers/media/pci/intel/ipu3/ipu3-cio2.h
> @@ -437,4 +437,10 @@ static inline struct cio2_queue 
> *vb2q_to_cio2_queue(struct vb2_queue *vq)
>   return container_of(vq, struct cio2_queue, vbq);
>  }
>  
> +#if IS_ENABLED(CONFIG_CIO2_BRIDGE)
> +int cio2_bridge_init(struct pci_dev *cio2);
> +#else
> +int cio2_bridge_init(struct pci_dev *cio2) { return 0; }
> +#endif
> +
>  #endif

-- 
Regards,

Laurent Pinchart


Re: [PATCH 11/18] media: v4l2-core: v4l2-async: Check possible match in match_fwnode based on sd->fwnode->secondary

2020-11-30 Thread Laurent Pinchart
Hi Daniel,

Thank you for the patch.

On Mon, Nov 30, 2020 at 01:31:22PM +, Daniel Scally wrote:
> Where the fwnode graph is comprised of software_nodes, these will be
> assigned as the secondary to dev->fwnode. Check the v4l2_subdev's fwnode
> for a secondary and attempt to match against it during match_fwnode() to
> accommodate that possibility.
> 
> Signed-off-by: Daniel Scally 

Reviewed-by: Laurent Pinchart 

> ---
> Changes since RFC v3:
> 
>   - None
> 
>  drivers/media/v4l2-core/v4l2-async.c | 8 
>  1 file changed, 8 insertions(+)
> 
> diff --git a/drivers/media/v4l2-core/v4l2-async.c 
> b/drivers/media/v4l2-core/v4l2-async.c
> index e3ab003a6c85..6486dbde784f 100644
> --- a/drivers/media/v4l2-core/v4l2-async.c
> +++ b/drivers/media/v4l2-core/v4l2-async.c
> @@ -87,6 +87,14 @@ static bool match_fwnode(struct v4l2_async_notifier 
> *notifier,
>   if (sd->fwnode == asd->match.fwnode)
>   return true;
>  
> + /*
> +  * Check the same situation for any possible secondary assigned to the
> +  * subdev's fwnode
> +  */
> + if ((!IS_ERR_OR_NULL(sd->fwnode->secondary)) &&
> + sd->fwnode->secondary == asd->match.fwnode)
> + return true;
> +
>   /*
>* Otherwise, check if the sd fwnode and the asd fwnode refer to an
>* endpoint or a device. If they're of the same type, there's no match.

-- 
Regards,

Laurent Pinchart


Re: [PATCH 07/18] software_node: Add support for fwnode_graph*() family of functions

2020-11-30 Thread Laurent Pinchart
atic struct fwnode_handle *
> +software_node_graph_get_remote_endpoint(const struct fwnode_handle *fwnode)
> +{
> + struct swnode *swnode = to_swnode(fwnode);
> + const struct software_node_ref_args *ref;
> + const struct property_entry *prop;
> +
> + if (!swnode)
> + return NULL;
> +
> + prop = property_entry_get(swnode->node->properties, "remote-endpoint");
> + if (!prop || prop->type != DEV_PROP_REF || prop->is_inline)
> + return NULL;
> +
> + ref = prop->pointer;
> +
> + return software_node_get(software_node_fwnode(ref[0].node));
> +}
> +
> +static struct fwnode_handle *
> +software_node_graph_get_port_parent(struct fwnode_handle *fwnode)
> +{
> + struct swnode *swnode = to_swnode(fwnode);
> + struct fwnode_handle *parent;
> +
> + if (!strcmp(swnode->parent->node->name, "ports"))
> + parent = >parent->parent->fwnode;
> + else
> + parent = >parent->fwnode;
> +
> + return software_node_get(parent);
> +}
> +
> +static int
> +software_node_graph_parse_endpoint(const struct fwnode_handle *fwnode,
> +struct fwnode_endpoint *endpoint)
> +{
> + struct swnode *swnode = to_swnode(fwnode);
> + int ret;
> +
> + ret = kstrtou32(swnode->parent->node->name + 4, 10, >port);

If we use port@, s/4/5/. But I suppose we also want to support the case
where a single port is used, with its name set to "port" ? The logic
would then need to be a tad more complex. Not sure if the consistency is
worth the additional complexity, up to you.

> + if (ret)
> + return ret;
> +
> + endpoint->id = swnode->id;
> + endpoint->local_fwnode = fwnode;
> +
> + return 0;
> +}
> +
>  static const struct fwnode_operations software_node_ops = {
>   .get = software_node_get,
>   .put = software_node_put,
> @@ -551,7 +655,11 @@ static const struct fwnode_operations software_node_ops 
> = {
>   .get_parent = software_node_get_parent,
>   .get_next_child_node = software_node_get_next_child,
>   .get_named_child_node = software_node_get_named_child_node,
> - .get_reference_args = software_node_get_reference_args
> + .get_reference_args = software_node_get_reference_args,
> + .graph_get_next_endpoint = software_node_graph_get_next_endpoint,
> + .graph_get_remote_endpoint = software_node_graph_get_remote_endpoint,
> + .graph_get_port_parent = software_node_graph_get_port_parent,
> + .graph_parse_endpoint = software_node_graph_parse_endpoint,
>  };
>  
>  /* 
> -- */

-- 
Regards,

Laurent Pinchart


Re: [PATCH 08/18] lib/test_printf.c: Use helper function to unwind array of software_nodes

2020-11-30 Thread Laurent Pinchart
Hi Daniel,

Thank you for the patch.

On Mon, Nov 30, 2020 at 01:31:19PM +, Daniel Scally wrote:
> Use the software_node_unregister_nodes() helper function to unwind this
> array in a cleaner way.
> 
> Acked-by: Petr Mladek 
> Reviewed-by: Andy Shevchenko 
> Suggested-by: Andy Shevchenko 
> Signed-off-by: Daniel Scally 

Reviewed-by: Laurent Pinchart 

> ---
> Changes since RFC v3:
> 
>   Changed the called function name - didn't drop the tags since it's
>   such a trivial change, hope that's alright!
> 
>  lib/test_printf.c | 4 +---
>  1 file changed, 1 insertion(+), 3 deletions(-)
> 
> diff --git a/lib/test_printf.c b/lib/test_printf.c
> index 7ac87f18a10f..7d60f24240a4 100644
> --- a/lib/test_printf.c
> +++ b/lib/test_printf.c
> @@ -644,9 +644,7 @@ static void __init fwnode_pointer(void)
>   test(second_name, "%pfwP", software_node_fwnode([1]));
>   test(third_name, "%pfwP", software_node_fwnode([2]));
>  
> - software_node_unregister([2]);
> - software_node_unregister([1]);
> - software_node_unregister([0]);
> + software_node_unregister_nodes(softnodes);
>  }
>  
>  static void __init

-- 
Regards,

Laurent Pinchart


Re: [PATCH 06/18] software_node: amend software_node_unregister_node_group() to perform unregistration of array in reverse order to be consistent with software_node_unregister_nodes()

2020-11-30 Thread Laurent Pinchart
Hi Daniel,

Thank you for the patch.

The subject line is very long. We try to keep it within a 72 characters
limit in the kernel. That can be a challenge sometimes, and expections
can be accepted, but this one is relly long.

(The same comment holds for other patches in the series)

On Mon, Nov 30, 2020 at 01:31:17PM +, Daniel Scally wrote:
> To maintain consistency with software_node_unregister_nodes(), reverse
> the order in which the software_node_unregister_node_group() function
> unregisters nodes.
> 
> Suggested-by: Andy Shevchenko 
> Signed-off-by: Daniel Scally 

I"d squash this with the previous patch to avoid introducing an
inconsistency.

Reviewed-by: Laurent Pinchart 

> ---
> Changes since v3:
> 
>   Patch introduced
> 
>  drivers/base/swnode.c | 5 -
>  1 file changed, 4 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/base/swnode.c b/drivers/base/swnode.c
> index d39e1c76d98d..9bd0bb77ad5b 100644
> --- a/drivers/base/swnode.c
> +++ b/drivers/base/swnode.c
> @@ -782,7 +782,10 @@ void software_node_unregister_node_group(const struct 
> software_node **node_group
>   if (!node_group)
>   return;
>  
> - for (i = 0; node_group[i]; i++)
> + while (node_group[i]->name)
> + i++;
> +
> + while (i--)
>   software_node_unregister(node_group[i]);
>  }
>  EXPORT_SYMBOL_GPL(software_node_unregister_node_group);

-- 
Regards,

Laurent Pinchart


Re: [PATCH 05/18] software_node: Alter software_node_unregister_nodes() to unregister the array in reverse order

2020-11-30 Thread Laurent Pinchart
Hi Daniel,

Thank you for the patch.

On Mon, Nov 30, 2020 at 01:31:16PM +, Daniel Scally wrote:
> Software nodes that are children of another software node should be
> unregistered before their parent. To allow easy unregistering of an array
> of software_nodes ordered parent to child, reverse the order in which
> this function unregisters software_nodes.
> 
> Suggested-by: Andy Shevchenko 
> Signed-off-by: Daniel Scally 

Reviewed-by: Laurent Pinchart 

> ---
> Changes since RFC v3:
> 
>   Switched this functionality from a new function to replacing
>   the existing software_nodes_unregister_nodes()
> 
>  drivers/base/swnode.c | 19 ---
>  1 file changed, 12 insertions(+), 7 deletions(-)
> 
> diff --git a/drivers/base/swnode.c b/drivers/base/swnode.c
> index af7930b3679e..d39e1c76d98d 100644
> --- a/drivers/base/swnode.c
> +++ b/drivers/base/swnode.c
> @@ -720,20 +720,25 @@ EXPORT_SYMBOL_GPL(software_node_register_nodes);
>  
>  /**
>   * software_node_unregister_nodes - Unregister an array of software nodes
> - * @nodes: Zero terminated array of software nodes to be unregistered
> + * @nodes: Zero terminated array of software nodes to be unregistered. If
> + * parent pointers are set up in any of the software nodes then the array
> + * MUST be ordered such that parents come before their children.
>   *
>   * Unregister multiple software nodes at once.
>   *
> - * NOTE: Be careful using this call if the nodes had parent pointers set up 
> in
> - * them before registering.  If so, it is wiser to remove the nodes
> - * individually, in the correct order (child before parent) instead of 
> relying
> - * on the sequential order of the list of nodes in the array.
> + * NOTE: If you are uncertain whether the array is ordered such that
> + * parents will be unregistered before their children, it is wiser to
> + * remove the nodes individually, in the correct order (child before
> + * parent).
>   */
>  void software_node_unregister_nodes(const struct software_node *nodes)
>  {
> - int i;
> + unsigned int i = 0;
> +
> + while (nodes[i].name)
> + i++;
>  
> - for (i = 0; nodes[i].name; i++)
> + while (i--)
>   software_node_unregister([i]);
>  }
>  EXPORT_SYMBOL_GPL(software_node_unregister_nodes);

-- 
Regards,

Laurent Pinchart


Re: [PATCH 04/18] software_node: Enforce parent before child ordering of nodes array for software_node_register_nodes()

2020-11-30 Thread Laurent Pinchart
Hi Daniel,

Thank you for the patch.

On Mon, Nov 30, 2020 at 01:31:15PM +, Daniel Scally wrote:
> Registering software_nodes with the .parent member set to point to a
> currently unregistered software_node has the potential for problems,
> so enforce parent -> child ordering in arrays passed to this function.
> 
> Suggested-by: Andy Shevchenko 
> Signed-off-by: Daniel Scally 
> ---
> Changes since RFC v3:
> 
>   Patch introduced
> 
>  drivers/base/swnode.c | 15 +++
>  1 file changed, 11 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/base/swnode.c b/drivers/base/swnode.c
> index 615a0c93e116..af7930b3679e 100644
> --- a/drivers/base/swnode.c
> +++ b/drivers/base/swnode.c
> @@ -700,14 +700,21 @@ int software_node_register_nodes(const struct 
> software_node *nodes)
>   int i;
>  
>   for (i = 0; nodes[i].name; i++) {
> + if (nodes[i].parent)
> + if (!software_node_to_swnode(nodes[i].parent)) {
> + ret = -EINVAL;
> + goto err_unregister_nodes;
> + }
> +
>   ret = software_node_register([i]);
> - if (ret) {
> - software_node_unregister_nodes(nodes);
> - return ret;
> - }
> + if (ret)
> +         goto err_unregister_nodes;
>   }
>  
>   return 0;

I'd add a blank line here.

Reviewed-by: Laurent Pinchart 

> +err_unregister_nodes:
> + software_node_unregister_nodes(nodes);
> + return ret;
>  }
>  EXPORT_SYMBOL_GPL(software_node_register_nodes);
>  

-- 
Regards,

Laurent Pinchart


Re: [PATCH 04/18] software_node: Enforce parent before child ordering of nodes array for software_node_register_nodes()

2020-11-30 Thread Laurent Pinchart
On Mon, Nov 30, 2020 at 06:11:52PM +0200, Laurent Pinchart wrote:
> Hi Daniel,
> 
> Thank you for the patch.
> 
> On Mon, Nov 30, 2020 at 01:31:15PM +, Daniel Scally wrote:
> > Registering software_nodes with the .parent member set to point to a
> > currently unregistered software_node has the potential for problems,
> > so enforce parent -> child ordering in arrays passed to this function.
> > 
> > Suggested-by: Andy Shevchenko 
> > Signed-off-by: Daniel Scally 
> > ---
> > Changes since RFC v3:
> > 
> > Patch introduced
> > 
> >  drivers/base/swnode.c | 15 +++
> >  1 file changed, 11 insertions(+), 4 deletions(-)
> > 
> > diff --git a/drivers/base/swnode.c b/drivers/base/swnode.c
> > index 615a0c93e116..af7930b3679e 100644
> > --- a/drivers/base/swnode.c
> > +++ b/drivers/base/swnode.c
> > @@ -700,14 +700,21 @@ int software_node_register_nodes(const struct 
> > software_node *nodes)
> > int i;
> >  
> > for (i = 0; nodes[i].name; i++) {
> > +   if (nodes[i].parent)
> > +   if (!software_node_to_swnode(nodes[i].parent)) {
> > +   ret = -EINVAL;
> > +   goto err_unregister_nodes;
> > +   }
> > +
> > ret = software_node_register([i]);
> > -   if (ret) {
> > -   software_node_unregister_nodes(nodes);
> > -   return ret;
> > -   }
> > +   if (ret)
> > +   goto err_unregister_nodes;
> > }
> >  
> > return 0;
> 
> I'd add a blank line here.
> 
> Reviewed-by: Laurent Pinchart 

I spoke a bit too soon. Could you update the documentation of the
function to explain this new requirement ?

> > +err_unregister_nodes:
> > +   software_node_unregister_nodes(nodes);
> > +   return ret;
> >  }
> >  EXPORT_SYMBOL_GPL(software_node_register_nodes);
> >  
> 
> -- 
> Regards,
> 
> Laurent Pinchart

-- 
Regards,

Laurent Pinchart


Re: [PATCH 03/18] software_node: Fix failure to put() and get() references to children in software_node_get_next_child()

2020-11-30 Thread Laurent Pinchart
Hi Daniel,

Thank you for the patch.

On Mon, Nov 30, 2020 at 01:31:14PM +, Daniel Scally wrote:
> The software_node_get_next_child() function currently does not hold
> references to the child software_node that it finds or put the ref that
> is held against the old child - fix that.
> 
> Signed-off-by: Daniel Scally 

Reviewed-by: Laurent Pinchart 

> ---
> Changes since RFC v3:
> 
>   Put reference to previous child.
> 
>  drivers/base/swnode.c | 8 ++--
>  1 file changed, 6 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/base/swnode.c b/drivers/base/swnode.c
> index 010828fc785b..615a0c93e116 100644
> --- a/drivers/base/swnode.c
> +++ b/drivers/base/swnode.c
> @@ -443,14 +443,18 @@ software_node_get_next_child(const struct fwnode_handle 
> *fwnode,
>   struct swnode *c = to_swnode(child);
>  
>   if (!p || list_empty(>children) ||
> - (c && list_is_last(>entry, >children)))
> + (c && list_is_last(>entry, >children))) {
> + fwnode_handle_put(child);
>   return NULL;
> + }
>  
>   if (c)
>   c = list_next_entry(c, entry);
>   else
>   c = list_first_entry(>children, struct swnode, entry);
> - return >fwnode;
> +
> + fwnode_handle_put(child);
> + return fwnode_handle_get(>fwnode);
>  }
>  
>  static struct fwnode_handle *

-- 
Regards,

Laurent Pinchart


Re: [PATCH 02/18] property: Add support for calling fwnode_graph_get_endpoint_by_id() for fwnode->secondary

2020-11-30 Thread Laurent Pinchart
Hi Daniel,

Thank you for the patch.

On Mon, Nov 30, 2020 at 01:31:13PM +, Daniel Scally wrote:
> This function is used to find fwnode endpoints against a device. In
> some instances those endpoints are software nodes which are children of
> fwnode->secondary. Add support to fwnode_graph_get_endpoint_by_id() to
> find those endpoints by recursively calling itself passing the ptr to
> fwnode->secondary in the event no endpoint is found for the primary.
> 
> Signed-off-by: Daniel Scally 

Reviewed-by: Laurent Pinchart 

> ---
> Changes since RFC v3:
> 
>   Patch introduced. In discussion in the last submission I noted
>   that the CIO2 device doesn't have an ACPI fwnode - that turns
>   out to be true for _some_ devices but not others, so we need
>   this function to check the secondary too.
> 
>  drivers/base/property.c | 4 
>  1 file changed, 4 insertions(+)
> 
> diff --git a/drivers/base/property.c b/drivers/base/property.c
> index a5ca2306796f..4ece6b086e36 100644
> --- a/drivers/base/property.c
> +++ b/drivers/base/property.c
> @@ -1162,6 +1162,10 @@ fwnode_graph_get_endpoint_by_id(const struct 
> fwnode_handle *fwnode,
>   best_ep_id = fwnode_ep.id;
>   }
>  
> + if (!best_ep && fwnode && !IS_ERR_OR_NULL(fwnode->secondary))
> + return fwnode_graph_get_endpoint_by_id(fwnode->secondary, port,
> +endpoint, flags);
> +
>   return best_ep;
>  }
>  EXPORT_SYMBOL_GPL(fwnode_graph_get_endpoint_by_id);

-- 
Regards,

Laurent Pinchart


Re: [PATCH 01/18] property: Return true in fwnode_device_is_available for node types that do not implement this operation

2020-11-30 Thread Laurent Pinchart
Hi Daniel,

Thank you for the patch.

On Mon, Nov 30, 2020 at 01:31:12PM +, Daniel Scally wrote:
> Some types of fwnode_handle do not implement the device_is_available()
> check, such as those created by software_nodes. There isn't really a
> meaningful way to check for the availability of a device that doesn't
> actually exist, so if the check isn't implemented just assume that the
> "device" is present.
> 
> Suggested-by: Laurent Pinchart 
> Signed-off-by: Daniel Scally 

Reviewed-by: Laurent Pinchart 

> ---
> Changes since RFC v3:
> 
>   patch introduced
> 
>  drivers/base/property.c | 5 +
>  1 file changed, 5 insertions(+)
> 
> diff --git a/drivers/base/property.c b/drivers/base/property.c
> index 4c43d30145c6..a5ca2306796f 100644
> --- a/drivers/base/property.c
> +++ b/drivers/base/property.c
> @@ -785,9 +785,14 @@ EXPORT_SYMBOL_GPL(fwnode_handle_put);
>  /**
>   * fwnode_device_is_available - check if a device is available for use
>   * @fwnode: Pointer to the fwnode of the device.
> + *
> + * For fwnode node types that don't implement the .device_is_available()
> + * operation, this function returns true.
>   */
>  bool fwnode_device_is_available(const struct fwnode_handle *fwnode)
>  {
> + if (!fwnode_has_op(fwnode, device_is_available))
> + return true;
>   return fwnode_call_bool_op(fwnode, device_is_available);
>  }
>  EXPORT_SYMBOL_GPL(fwnode_device_is_available);

-- 
Regards,

Laurent Pinchart


Re: [PATCH v5 2/3] media: atmel: introduce microchip csi2dc driver

2020-11-17 Thread Laurent Pinchart
t; > +   ret = v4l2_fwnode_endpoint_parse(of_fwnode_handle(sink_node),
> > +_endpoint);
> 
> Same, set sink_endpoint.bus_type if you know it's MBUS_PARALLEL
> 
> > +
> > +   if (!sink_node || ret) {
> 
> If parsing fail you don't return an error but continue registering the
> notifier and potentially end up registering the async subdev for this
> entity even if the endpoint parsing failed.
> 
> > +   dev_info(csi2dc->dev,
> > +"missing sink node at %s, data pipe available only.\n",
> > +of_node->full_name);
> > +   } else {
> > +   csi2dc->video_pipe = true;
> 
> video_pipe is unused it seems
> 
> > +
> > +   dev_dbg(csi2dc->dev, "block %s %d.%d->%d.%d video pipeline\n",
> > +   of_node->full_name, input_endpoint.base.port,
> > +   input_endpoint.base.id, sink_endpoint.base.port,
> > +   sink_endpoint.base.id);
> > +   }
> > +
> > +   of_node_put(sink_node);
> > +   of_node_put(input_node);
> > +
> > +   /* prepare async notifier for subdevice completion */
> > +   return csi2dc_prepare_notifier(csi2dc, input_parent);
> > +}
> > +
> > +static void csi2dc_workq_handler(struct work_struct *workq)
> > +{
> > +   struct csi2dc_device *csi2dc = container_of(workq,
> > +   struct csi2dc_device, workq);
> > +   int ret;
> > +
> > +   if (v4l2_async_register_subdev(>csi2dc_sd))
> > +   dev_dbg(csi2dc->dev, "failed to register the subdevice\n");
> 
> That's peculiar, why do you have to schedule this to a workqueue
> instead of doing this in the complete() callback ?
> 
> > +
> > +   ret = csi2dc_power(csi2dc, true);
> > +   if (ret < 0)
> > +   v4l2_err(>v4l2_dev, "failed to power on\n");
> 
> Should the device be powered on at s_stream time ? Possibly with a
> pm_runtime_get_sync() call ? I see you register pm_runtime operations,
> but never call get_sync() or _put().
> 
> What if CONFIG_PM not selected ? Should this driver select it ? Do you
> have use cases where that's not possible ?
> 
> > +}
> > +
> > +static int csi2dc_probe(struct platform_device *pdev)
> > +{
> > +   struct device *dev = >dev;
> > +   struct csi2dc_device *csi2dc;
> > +   struct resource *res = NULL;
> > +   int ret = 0;
> > +
> > +   csi2dc = devm_kzalloc(dev, sizeof(*csi2dc), GFP_KERNEL);
> > +   if (!csi2dc)
> > +   return -ENOMEM;
> > +
> > +   csi2dc->dev = dev;
> > +
> > +   res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> > +   if (!res)
> > +   return -EINVAL;
> 
> devm_ioremap_resource() checks for the validity of 'res' so you can
> drop the previous two lines
> 
> > +
> > +   csi2dc->base = devm_ioremap_resource(dev, res);
> > +
> 
> Is the empy line intentional, sometimes you have one, sometimes you
> don't ?
> 
> > +   if (IS_ERR(csi2dc->base)) {
> > +   dev_err(dev, "base address not set\n");
> 
> 
> > +   return PTR_ERR(csi2dc->base);
> > +   }
> > +
> > +   csi2dc->pclk = devm_clk_get(dev, "pclk");
> > +   if (IS_ERR(csi2dc->pclk)) {
> > +   ret = PTR_ERR(csi2dc->pclk);
> > +   dev_err(dev, "failed to get pclk: %d\n", ret);
> > +   return ret;
> 
> Just return PTR_ERR instead of assigning to ret
> 
> > +   }
> > +
> > +   ret = clk_prepare_enable(csi2dc->pclk);
> > +   if (ret) {
> > +   dev_err(dev, "failed to enable pclk: %d\n", ret);
> > +   return ret;
> > +   }
> 
> Has this clock to be enabled here or can it be done in the
> pm_runtime callback ?
> 
> > +
> > +   csi2dc->scck = devm_clk_get(dev, "scck");
> > +   if (IS_ERR(csi2dc->scck)) {
> > +   ret = PTR_ERR(csi2dc->scck);
> > +   dev_err(dev, "failed to get scck: %d\n", ret);
> > +   goto csi2dc_clk_fail;
> > +   }
> > +
> > +   ret = v4l2_device_register(dev, >v4l2_dev);
> > +   if (ret) {
> > +   dev_err(dev, "unable to register v4l2 device.\n");
> > +   goto csi2dc_clk_fail;
> > +   }
> > +
> > +   v4l2_subdev_init(>csi2dc_sd, _subdev_ops);
> > +
> > +   csi2dc->csi2dc_sd.owner = THIS_MODULE;
> > +   csi2dc->csi2dc_sd.dev = dev;
> > +   snprintf(csi2dc->csi2dc_sd.name, sizeof(csi2dc->csi2dc_sd.name),
> > +"CSI2DC.0");
> > +
> > +   csi2dc->csi2dc_sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
> > +   csi2dc->csi2dc_sd.entity.function = MEDIA_ENT_F_VID_IF_BRIDGE;
> > +   csi2dc->pads[CSI2DC_PAD_SINK].flags = MEDIA_PAD_FL_SINK;
> > +   csi2dc->pads[CSI2DC_PAD_SOURCE].flags = MEDIA_PAD_FL_SOURCE;
> 
> Isn't the source pad presence conditional to the presence of
> port@1 ?
> 
> > +
> > +   ret = media_entity_pads_init(>csi2dc_sd.entity, CSI2DC_PADS_NUM,
> > +csi2dc->pads);
> > +   if (ret < 0) {
> > +   dev_err(dev, "media entity init failed\n");
> > +   goto csi2dc_probe_entity_err;
> > +   }
> > +
> > +   v4l2_set_subdevdata(>csi2dc_sd, pdev);
> > +
> > +   platform_set_drvdata(pdev, >csi2dc_sd);
> > +
> > +   INIT_WORK(>workq, csi2dc_workq_handler);
> > +
> > +   ret = csi2dc_of_parse(csi2dc, dev->of_node);
> > +   if (ret)
> > +   goto csi2dc_probe_entity_err;
> > +
> > +   dev_info(dev, "Microchip CSI2DC version %x\n",
> > +csi2dc_readl(csi2dc, CSI2DC_VERSION));
> > +
> > +   pm_runtime_set_active(dev);
> > +   pm_runtime_enable(dev);
> > +   pm_request_idle(dev);
> > +
> > +   return 0;
> > +
> > +csi2dc_probe_entity_err:
> > +   media_entity_cleanup(>csi2dc_sd.entity);
> > +   v4l2_device_unregister(>v4l2_dev);
> > +csi2dc_clk_fail:
> > +   clk_disable_unprepare(csi2dc->pclk);
> > +   return ret;
> > +}
> > +
> > +static int csi2dc_remove(struct platform_device *pdev)
> > +{
> > +   struct v4l2_subdev *csi2dc_sd = platform_get_drvdata(pdev);
> > +   struct csi2dc_device *csi2dc = csi2dc_sd_to_csi2dc_device(csi2dc_sd);
> > +
> > +   pm_runtime_disable(>dev);
> > +
> > +   v4l2_async_unregister_subdev(>csi2dc_sd);
> > +   csi2dc_cleanup_notifier(csi2dc);
> > +   media_entity_cleanup(>csi2dc_sd.entity);
> > +   v4l2_device_unregister(>v4l2_dev);
> > +   clk_disable_unprepare(csi2dc->pclk);
> > +
> > +   return 0;
> > +}
> > +
> > +static int __maybe_unused csi2dc_runtime_suspend(struct device *dev)
> > +{
> > +   struct csi2dc_device *csi2dc = dev_get_drvdata(dev);
> > +
> > +   return csi2dc_power(csi2dc, false);
> > +}
> > +
> > +static int __maybe_unused csi2dc_runtime_resume(struct device *dev)
> > +{
> > +   struct csi2dc_device *csi2dc = dev_get_drvdata(dev);
> > +
> > +   return csi2dc_power(csi2dc, true);
> > +}
> > +
> > +static const struct dev_pm_ops csi2dc_dev_pm_ops = {
> > +   SET_RUNTIME_PM_OPS(csi2dc_runtime_suspend, csi2dc_runtime_resume, NULL)
> > +};
> > +
> > +static const struct of_device_id csi2dc_of_match[] = {
> > +   { .compatible = "microchip,sama7g5-csi2dc" },
> > +   { }
> > +};
> > +
> > +MODULE_DEVICE_TABLE(of, csi2dc_of_match);
> > +
> > +static struct platform_driver csi2dc_driver = {
> > +   .probe  = csi2dc_probe,
> > +   .remove = csi2dc_remove,
> > +   .driver = {
> > +   .name   = "microchip-csi2dc",
> > +   .pm = _dev_pm_ops,
> > +   .of_match_table = of_match_ptr(csi2dc_of_match),
> > +   },
> > +};
> > +
> > +module_platform_driver(csi2dc_driver);
> > +
> > +MODULE_AUTHOR("Eugen Hristev ");
> > +MODULE_DESCRIPTION("Microchip CSI2 Demux Controller driver");
> > +MODULE_LICENSE("GPL v2");
> > +MODULE_SUPPORTED_DEVICE("video");
> 
> For my education, what's MODULE_SUPPORTED_DEVICE for ?

It's "not yet implemented" since 2005, I think it can be dropped :-)

-- 
Regards,

Laurent Pinchart


Re: [RFC PATCH v3 9/9] ipu3-cio2: Add functionality allowing software_node connections to sensors on platforms designed for Windows

2020-11-16 Thread Laurent Pinchart
Hi Andy,

On Mon, Nov 16, 2020 at 03:57:17PM +0200, Andy Shevchenko wrote:
> On Mon, Nov 16, 2020 at 10:53 AM Laurent Pinchart wrote:
> > On Fri, Nov 13, 2020 at 09:45:00PM +0200, Andy Shevchenko wrote:
> > > On Fri, Nov 13, 2020 at 6:22 PM Laurent Pinchart wrote:
> > > > On Fri, Nov 13, 2020 at 10:02:30AM +, Dan Scally wrote:
> > > > > On 29/10/2020 22:51, Laurent Pinchart wrote:
> > > > > > On Fri, Oct 30, 2020 at 12:22:15AM +0200, Andy Shevchenko wrote:
> > > > > >> On Thu, Oct 29, 2020 at 11:29:30PM +0200, Laurent Pinchart wrote:
> > >
> > > ...
> > >
> > > > > >> In this case we probably need something like
> > > > > >>
> > > > > >> struct acpi_device *
> > > > > >> acpi_dev_get_next_match_dev(struct acpi_device *adev,
> > > > > >>const char *hid, const char *uid, s64 hrv)
> > > > > >> {
> > > > > >>struct device *start = adev ? >dev : NULL;
> > > > > >>...
> > > > > >>dev = bus_find_device(_bus_type, start, , 
> > > > > >> acpi_dev_match_cb);
> > > > > >>...
> > > > > >> }
> > > > > >>
> > > > > >> in drivers/acpi/utils.c and
> > > > > >>
> > > > > >> static inline struct acpi_device *
> > > > > >> acpi_dev_get_first_match_dev(const char *hid, const char *uid, s64 
> > > > > >> hrv)
> > > > > >> {
> > > > > >>return acpi_dev_get_next_match_dev(NULL, hid, uid, hrv);
> > > > > >> }
> > > > > >>
> > > > > >> in include/linux/acpi.h.
> > > > > >>
> > > > > >> Then we may add
> > > > > >>
> > > > > >> #define for_each_acpi_dev_match(adev, hid, uid, hrv)   
> > > > > >> \
> > > > > >>for (adev = acpi_dev_get_first_match_dev(hid, uid, hrv);
> > > > > >> \
> > > > > >> adev;  
> > > > > >> \
> > > > > >> adev = acpi_dev_get_next_match_dev(adev, hid, uid, hrv))
> > > > > >
> > > > > > What the cio2-bridge code needs is indeed
> > > > > >
> > > > > > for each hid in supported hids:
> > > > > > for each acpi device that is compatible with hid:
> > > > > > ...
> > > > > >
> > > > > > which could also be expressed as
> > > > > >
> > > > > > for each acpi device:
> > > > > > if acpi device hid is in supported hids:
> > > > > > ...
> > > > > >
> > > > > > I don't mind either option, I'll happily follow the preference of 
> > > > > > the
> > > > > > ACPI maintainers.
> > > > >
> > > > > Does this need raising elsewhere then? The original idea of just
> > > > > bus_for_each_dev(_bus_type...) I have now tested and it works 
> > > > > fine,
> > > > > but it does mean that I need to export acpi_bus_type (currently that
> > > > > symbol's not available)...that seems much simpler to me but I'm not 
> > > > > sure
> > > > > whether that's something to avoid, and if so whether Andy's approach 
> > > > > is
> > > > > better.
> > > > >
> > > > > Thoughts?
> > > >
> > > > I like simple options :-) A patch to export acpi_bus_type, with enough
> > > > context in the commit message (and in the cover latter of the series),
> > > > should be enough to provide all the information the ACPI maintainers
> > > > need to decide which option is best. With a bit of luck that patch will
> > > > be considered the best option and no extra work will be needed.
> > >
> > > The problem with ACPI bus is that it is not as simple as other buses,
> > > i.e. it may have purely ACPI devices along with *companion* devices,
> > > which are usually represented by platform bus. On top of that for
> > > several ACPI devices there can be one physical node and it will be not

Re: [PATCH v4 1/8] media: i2c: Add driver for RDACM21 camera module

2020-11-16 Thread Laurent Pinchart
 */
> > > + ret = max9271_set_serial_link(dev->serializer, false);
> > > + if (ret)
> > > + return ret;
> > > +
> > > + /* Set GPO high to hold OV490 in reset during max9271 configuration. */
> > > + ret = max9271_set_gpios(dev->serializer, MAX9271_GPO);
> > > + if (ret)
> > > + return ret;
> > > +
> > > + /* Configure I2C bus at 105Kbps speed and configure GMSL link. */
> > > + ret = max9271_configure_i2c(dev->serializer,
> > > + MAX9271_I2CSLVSH_469NS_234NS |
> > > + MAX9271_I2CSLVTO_1024US |
> > > + MAX9271_I2CMSTBT_105KBPS);
> > > + if (ret)
> > > + return ret;
> > > +
> > > + ret = max9271_configure_gmsl_link(dev->serializer);
> > > + if (ret)
> > > + return ret;
> > > +
> > > + ret = max9271_set_address(dev->serializer, dev->addrs[0]);
> > > + if (ret)
> > > + return ret;
> > > + dev->serializer->client->addr = dev->addrs[0];
> > > +
> > > + /*
> > > +  * Release OV490 from reset and program address translation
> > > +  * before performing OV490 configuration.
> > > +  */
> > > + ret = max9271_clear_gpios(dev->serializer, MAX9271_GPO);
> > > + if (ret)
> > > + return ret;
> > > +
> > > + ret = max9271_set_translation(dev->serializer, dev->addrs[1],
> > > +   OV490_I2C_ADDRESS);
> > > + if (ret)
> > > + return ret;
> > > + dev->isp->addr = dev->addrs[1];
> > > +
> > > + ret = ov490_initialize(dev);
> > > + if (ret)
> > > + return ret;
> > > +
> > > + /*
> > > +  * Set reverse channel high threshold to increase noise immunity.
> > > +  *
> > > +  * This should be compensated by increasing the reverse channel
> > > +  * amplitude on the remote deserializer side.
> > > +  */
> > > + ret = max9271_set_high_threshold(dev->serializer, true);
> > > + if (ret)
> > > + return ret;
> > > +
> > > + return 0;
> > > +}
> > > +
> > > +static int rdacm21_probe(struct i2c_client *client)
> > > +{
> > > + struct rdacm21_device *dev;
> > > + struct fwnode_handle *ep;
> > > + int ret;
> > > +
> > > + dev = devm_kzalloc(>dev, sizeof(*dev), GFP_KERNEL);
> > > + if (!dev)
> > > + return -ENOMEM;
> > > + dev->dev = >dev;
> > > +
> > > + dev->serializer = devm_kzalloc(>dev, sizeof(*dev->serializer),
> > > +GFP_KERNEL);
> > > + if (!dev->serializer)
> > > + return -ENOMEM;
> > > +
> > > + dev->serializer->client = client;
> > > +
> > > + ret = of_property_read_u32_array(client->dev.of_node, "reg",
> > > +  dev->addrs, 2);
> > > + if (ret < 0) {
> > > + dev_err(dev->dev, "Invalid DT reg property: %d\n", ret);
> > > + return -EINVAL;
> > > + }
> > > +
> > > + /* Create the dummy I2C client for the sensor. */
> > > + dev->isp = i2c_new_dummy_device(client->adapter, OV490_I2C_ADDRESS);
> > > + if (IS_ERR(dev->isp))
> > > + return PTR_ERR(dev->isp);
> > > +
> > > + ret = rdacm21_initialize(dev);
> > > + if (ret < 0)
> > > + goto error;
> > > +
> > > + /* Initialize and register the subdevice. */
> > > + v4l2_i2c_subdev_init(>sd, client, _subdev_ops);
> > > + dev->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
> > > +
> > > + v4l2_ctrl_handler_init(>ctrls, 1);
> > > + v4l2_ctrl_new_std(>ctrls, NULL, V4L2_CID_PIXEL_RATE,
> > > +   OV10640_PIXEL_RATE, OV10640_PIXEL_RATE, 1,
> > > +   OV10640_PIXEL_RATE);
> > > + dev->sd.ctrl_handler = >ctrls;
> > > +
> > > + ret = dev->ctrls.error;
> > > + if (ret)
> > > + goto error_free_ctrls;
> > > +
> > > + dev->pad.flags = MEDIA_PAD_FL_SOURCE;
> > > + dev->sd.entity.flags |= MEDIA_ENT_F_CAM_SENSOR;
> > > + ret = media_entity_pads_init(>sd.entity, 1, >pad);
> > > + if (ret < 0)
> > > + goto error_free_ctrls;
> > > +
> > > + ep = fwnode_graph_get_next_endpoint(dev_fwnode(>dev), NULL);
> > > + if (!ep) {
> > > + dev_err(>dev,
> > > + "Unable to get endpoint in node %pOF\n",
> > > + client->dev.of_node);
> > > + ret = -ENOENT;
> > > + goto error_free_ctrls;
> > > + }
> > > + dev->sd.fwnode = ep;
> > > +
> > > + ret = v4l2_async_register_subdev(>sd);
> > > + if (ret)
> > > + goto error_put_node;
> > > +
> > > + return 0;
> > > +
> > > +error_put_node:
> > > + fwnode_handle_put(dev->sd.fwnode);
> > > +error_free_ctrls:
> > > + v4l2_ctrl_handler_free(>ctrls);
> > > +error:
> > > + i2c_unregister_device(dev->isp);
> > > +
> > > + return ret;
> > > +}
> > > +
> > > +static int rdacm21_remove(struct i2c_client *client)
> > > +{
> > > + struct rdacm21_device *dev = i2c_to_rdacm21(client);
> > > +
> > > + fwnode_handle_put(dev->sd.fwnode);
> > > + v4l2_async_unregister_subdev(>sd);
> > > + v4l2_ctrl_handler_free(>ctrls);
> > > + i2c_unregister_device(dev->isp);
> > > +
> > > + return 0;
> > > +}
> > > +
> > > +static const struct of_device_id rdacm21_of_ids[] = {
> > > + { .compatible = "imi,rdacm21" },
> > > + { }
> > > +};
> > > +MODULE_DEVICE_TABLE(of, rdacm21_of_ids);
> > > +
> > > +static struct i2c_driver rdacm21_i2c_driver = {
> > > + .driver = {
> > > + .name   = "rdacm21",
> > > + .of_match_table = rdacm21_of_ids,
> > > + },
> > > + .probe_new  = rdacm21_probe,
> > > + .remove = rdacm21_remove,
> > > +};
> > > +
> > > +module_i2c_driver(rdacm21_i2c_driver);
> > > +
> > > +MODULE_DESCRIPTION("GMSL Camera driver for RDACM21");
> > > +MODULE_AUTHOR("Jacopo Mondi, Kieran Bingham, Laurent Pinchart, Niklas 
> > > Söderlund, Vladimir Barinov");
> >
> > I think by this point you could chop MODULE_AUTHOR for this one down to
> > just you ;-)
> >
> >
> > A fairly arbitrary, and cursory
> >
> > Reviewed-by: Kieran Bingham 
> >
> > I'll be aiming to test this (series) as soon as I can too.
> 
> Thanks, let me know if I should submit for proper inclusion!
> 
> > > +MODULE_LICENSE("GPL v2");

-- 
Regards,

Laurent Pinchart


Re: [RFC PATCH v3 9/9] ipu3-cio2: Add functionality allowing software_node connections to sensors on platforms designed for Windows

2020-11-16 Thread Laurent Pinchart
Hi Andy,

On Fri, Nov 13, 2020 at 09:45:00PM +0200, Andy Shevchenko wrote:
> On Fri, Nov 13, 2020 at 6:22 PM Laurent Pinchart wrote:
> > On Fri, Nov 13, 2020 at 10:02:30AM +, Dan Scally wrote:
> > > On 29/10/2020 22:51, Laurent Pinchart wrote:
> > > > On Fri, Oct 30, 2020 at 12:22:15AM +0200, Andy Shevchenko wrote:
> > > >> On Thu, Oct 29, 2020 at 11:29:30PM +0200, Laurent Pinchart wrote:
> 
> ...
> 
> > > >> In this case we probably need something like
> > > >>
> > > >> struct acpi_device *
> > > >> acpi_dev_get_next_match_dev(struct acpi_device *adev,
> > > >>const char *hid, const char *uid, s64 hrv)
> > > >> {
> > > >>struct device *start = adev ? >dev : NULL;
> > > >>...
> > > >>dev = bus_find_device(_bus_type, start, , 
> > > >> acpi_dev_match_cb);
> > > >>...
> > > >> }
> > > >>
> > > >> in drivers/acpi/utils.c and
> > > >>
> > > >> static inline struct acpi_device *
> > > >> acpi_dev_get_first_match_dev(const char *hid, const char *uid, s64 hrv)
> > > >> {
> > > >>return acpi_dev_get_next_match_dev(NULL, hid, uid, hrv);
> > > >> }
> > > >>
> > > >> in include/linux/acpi.h.
> > > >>
> > > >> Then we may add
> > > >>
> > > >> #define for_each_acpi_dev_match(adev, hid, uid, hrv)   
> > > >> \
> > > >>for (adev = acpi_dev_get_first_match_dev(hid, uid, hrv);\
> > > >> adev;  \
> > > >> adev = acpi_dev_get_next_match_dev(adev, hid, uid, hrv))
> > > >
> > > > What the cio2-bridge code needs is indeed
> > > >
> > > > for each hid in supported hids:
> > > > for each acpi device that is compatible with hid:
> > > > ...
> > > >
> > > > which could also be expressed as
> > > >
> > > > for each acpi device:
> > > > if acpi device hid is in supported hids:
> > > > ...
> > > >
> > > > I don't mind either option, I'll happily follow the preference of the
> > > > ACPI maintainers.
> > >
> > > Does this need raising elsewhere then? The original idea of just
> > > bus_for_each_dev(_bus_type...) I have now tested and it works fine,
> > > but it does mean that I need to export acpi_bus_type (currently that
> > > symbol's not available)...that seems much simpler to me but I'm not sure
> > > whether that's something to avoid, and if so whether Andy's approach is
> > > better.
> > >
> > > Thoughts?
> >
> > I like simple options :-) A patch to export acpi_bus_type, with enough
> > context in the commit message (and in the cover latter of the series),
> > should be enough to provide all the information the ACPI maintainers
> > need to decide which option is best. With a bit of luck that patch will
> > be considered the best option and no extra work will be needed.
> 
> The problem with ACPI bus is that it is not as simple as other buses,
> i.e. it may have purely ACPI devices along with *companion* devices,
> which are usually represented by platform bus. On top of that for
> several ACPI devices there can be one physical node and it will be not
> so clear what you are exactly looking for by traversing acpi_bus_type.
> I believe it's hidden on purpose.

Maybe there's something I don't get, as I'm not very familiar with the
ACPI implementation in the kernel, but the code in the cio2-bridge,
unless I'm mistaken, is really interested in ACPI devices on the ACPI
bus, not companions or other devices related to the ACPI devices. The
iterators you have proposed above use bus_find_device() on
acpi_bus_type, so I don't really see how they make a difference from a
cio2-bridge point of view. Is your point that acpi_bus_type shouldn't be
exported because it could then be misused by *other* drivers ? Couldn't
those drivers then equally misuse the iterators ?

-- 
Regards,

Laurent Pinchart


Re: [RFC PATCH v3 9/9] ipu3-cio2: Add functionality allowing software_node connections to sensors on platforms designed for Windows

2020-11-13 Thread Laurent Pinchart
Hi Dan,

On Fri, Nov 13, 2020 at 10:02:30AM +, Dan Scally wrote:
> On 29/10/2020 22:51, Laurent Pinchart wrote:
> > On Fri, Oct 30, 2020 at 12:22:15AM +0200, Andy Shevchenko wrote:
> >> On Thu, Oct 29, 2020 at 11:29:30PM +0200, Laurent Pinchart wrote:
> >>> On Thu, Oct 29, 2020 at 10:26:56PM +0200, Andy Shevchenko wrote:
> >>>> On Thu, Oct 29, 2020 at 10:21 PM Laurent Pinchart wrote:
> >>>>> On Mon, Oct 26, 2020 at 06:10:50PM +0200, Andy Shevchenko wrote:
> >>>>>> On Sat, Oct 24, 2020 at 12:37:02PM +0300, Laurent Pinchart wrote:
> >>>>>>> On Sat, Oct 24, 2020 at 09:50:07AM +0100, Dan Scally wrote:
> >>>>>>>> On 24/10/2020 02:24, Laurent Pinchart wrote:
> >>>>>>>>> On Mon, Oct 19, 2020 at 11:59:03PM +0100, Daniel Scally wrote:
> >>>>>>>>>> +  adev = 
> >>>>>>>>>> acpi_dev_get_first_match_dev(supported_devices[i], NULL, -1);
> >>>>>>>>> What if there are multiple sensor of the same model ?
> >>>>>>>> Hmm, yeah, that would be a bit of a pickle. I guess the newer
> >>>>>>>> smartphones have multiple sensors on the back, which I presume are 
> >>>>>>>> the
> >>>>>>>> same model. So that will probably crop up at some point. How about
> >>>>>>>> instead I use bus_for_each_dev() and in the applied function check if
> >>>>>>>> the _HID is in the supported list?
> >>>>>>> Sounds good to me.
> >>>>>>>
> >>>>>>>>>> +  if (!adev)
> >>>>>>>>>> +  continue;
> >>>>>> Please, don't.
> >>>>>>
> >>>>>> If we have so weird ACPI tables it must be w/a differently. The all, 
> >>>>>> even badly
> >>>>>> formed, ACPI tables I have seen so far are using _UID to distinguish 
> >>>>>> instance
> >>>>>> of the device (see second parameter to the above function).
> >>>>>>
> >>>>>> If we meet the very broken table I would like rather to know about, 
> >>>>>> then
> >>>>>> silently think ahead what could be best.
> >>>>>>
> >>>>>> I.o.w. don't change this until we will have a real example of the 
> >>>>>> problematic
> >>>>>> firmware.
> >>>>> I'm not sure to follow you. Daniel's current code loops over all the
> >>>>> supported HID (as stored in the supported_devices table), and then gets
> >>>>> the first ACPI device for each of them. If multiple ACPI devices exist
> >>>>> with the same HID, we need to handle them all, so enumerating all ACPI
> >>>>> devices and checking whether their HID is one we handle seems to be the
> >>>>> right option to me.
> >>>> Devices with the same HID should be still different by another
> >>>> parameter in ACPI. The above mentioned call just uses the rough
> >>>> estimation for relaxed conditions. If you expect more than one device
> >>>> with the same HID how do you expect to distinguish them? The correct
> >>>> way is to use _UID. It may be absent, or set to a value. And this
> >>>> value should be unique (as per U letter in UID abbreviation). That
> >>>> said, the above is good enough till we find the firmware with the
> >>>> above true (several devices with the same HID). Until then the code is
> >>>> fine.
> >>> I expect those devices with the same _HID to have different _UID values,
> >>> yes. On the systems I've seen so far, that assumption is not violated,
> >>> and I don't think we need to already plan how we will support systems
> >>> where multiple devices would have the same _HID and _UID (within the
> >>> same scope). There's no disagreement there.
> >>>
> >>> My point is that supported_devices stores HID values, and doesn't care
> >>> about UID. The code loops over supported_devices, and for each entry,
> >>> calls acpi_dev_get_first_match_dev() and process the ACPI devices
> >>> returned by that call. We thus process at most one ACPI device per HID,
> >>> which isn't right.
> >>
> >> In this case we probably nee

Re: [PATCH v3 1/3] dt-bindings: Convert graph bindings to json-schema

2020-11-11 Thread Laurent Pinchart
Hi Rob,

On Wed, Nov 11, 2020 at 05:03:26PM -0600, Rob Herring wrote:
> On Wed, Nov 11, 2020 at 8:27 AM Laurent Pinchart wrote:
> > On Wed, Nov 11, 2020 at 08:25:40AM -0600, Rob Herring wrote:
> > > On Wed, Nov 11, 2020 at 8:00 AM Laurent Pinchart wrote:
> > > > On Mon, Nov 02, 2020 at 02:36:54PM -0600, Rob Herring wrote:
> > > > > From: Sameer Pujar 
> > > > >
> > > > > Convert device tree bindings of graph to YAML format. Currently 
> > > > > graph.txt
> > > > > doc is referenced in multiple files and all of these need to use 
> > > > > schema
> > > > > references. For now graph.txt is updated to refer to graph.yaml.
> > > > >
> > > > > For users of the graph binding, they should reference to the graph
> > > > > schema from either 'ports' or 'port' property:
> > > > >
> > > > > properties:
> > > > >   ports:
> > > > > type: object
> > > > > $ref: graph.yaml#/properties/ports
> > > > >
> > > > > properties:
> > > > >   port@0:
> > > > > description: What data this port has
> > > > >
> > > > >   ...
> > > > >
> > > > > Or:
> > > > >
> > > > > properties:
> > > > >   port:
> > > > > description: What data this port has
> > > > > type: object
> > > > > $ref: graph.yaml#/properties/port
> > > >
> > > > Sounds like a good approach.
> > > >
> > > > > Signed-off-by: Sameer Pujar 
> > > > > Acked-by: Philipp Zabel 
> > > > > Signed-off-by: Rob Herring 
> > > > > ---
> > > > > v3:
> > > > >  - Move port 'reg' to port@* and make required
> > > > >  - Make remote-endpoint required
> > > > >  - Add 'additionalProperties: true' now required
> > > > >  - Fix yamllint warnings
> > > > >
> > > > >  Documentation/devicetree/bindings/graph.txt  | 129 +---
> > > > >  Documentation/devicetree/bindings/graph.yaml | 199 
> > > > > +++
> > > > >  2 files changed, 200 insertions(+), 128 deletions(-)
> > > > >  create mode 100644 Documentation/devicetree/bindings/graph.yaml
> > >
> > > [...]
> > >
> > > > > diff --git a/Documentation/devicetree/bindings/graph.yaml 
> > > > > b/Documentation/devicetree/bindings/graph.yaml
> > > > > new file mode 100644
> > > > > index ..b56720c5a13e
> > > > > --- /dev/null
> > > > > +++ b/Documentation/devicetree/bindings/graph.yaml
> > > > > @@ -0,0 +1,199 @@
> > > > > +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> > > > > +%YAML 1.2
> > > > > +---
> > > > > +$id: http://devicetree.org/schemas/graph.yaml#
> > > > > +$schema: http://devicetree.org/meta-schemas/core.yaml#
> > > > > +
> > > > > +title: Common bindings for device graphs
> > > > > +
> > > > > +description: |
> > > > > +  The hierarchical organisation of the device tree is well suited to 
> > > > > describe
> > > > > +  control flow to devices, but there can be more complex connections 
> > > > > between
> > > > > +  devices that work together to form a logical compound device, 
> > > > > following an
> > > > > +  arbitrarily complex graph.
> > > > > +  There already is a simple directed graph between devices tree 
> > > > > nodes using
> > > > > +  phandle properties pointing to other nodes to describe connections 
> > > > > that
> > > > > +  can not be inferred from device tree parent-child relationships. 
> > > > > The device
> > > > > +  tree graph bindings described herein abstract more complex devices 
> > > > > that can
> > > > > +  have multiple specifiable ports, each of which can be linked to 
> > > > > one or more
> > > > > +  ports of other devices.
> > > > > +
> > > > > +  These common bindings do not contain any information about the 
> > > > > direction or
> > > > > +  type of the connections, they just map their existence. Specific

Re: [PATCH v3 1/3] dt-bindings: Convert graph bindings to json-schema

2020-11-11 Thread Laurent Pinchart
Hi Rob,

On Wed, Nov 11, 2020 at 08:25:40AM -0600, Rob Herring wrote:
> On Wed, Nov 11, 2020 at 8:00 AM Laurent Pinchart wrote:
> > On Mon, Nov 02, 2020 at 02:36:54PM -0600, Rob Herring wrote:
> > > From: Sameer Pujar 
> > >
> > > Convert device tree bindings of graph to YAML format. Currently graph.txt
> > > doc is referenced in multiple files and all of these need to use schema
> > > references. For now graph.txt is updated to refer to graph.yaml.
> > >
> > > For users of the graph binding, they should reference to the graph
> > > schema from either 'ports' or 'port' property:
> > >
> > > properties:
> > >   ports:
> > > type: object
> > > $ref: graph.yaml#/properties/ports
> > >
> > > properties:
> > >   port@0:
> > > description: What data this port has
> > >
> > >   ...
> > >
> > > Or:
> > >
> > > properties:
> > >   port:
> > > description: What data this port has
> > > type: object
> > > $ref: graph.yaml#/properties/port
> >
> > Sounds like a good approach.
> >
> > > Signed-off-by: Sameer Pujar 
> > > Acked-by: Philipp Zabel 
> > > Signed-off-by: Rob Herring 
> > > ---
> > > v3:
> > >  - Move port 'reg' to port@* and make required
> > >  - Make remote-endpoint required
> > >  - Add 'additionalProperties: true' now required
> > >  - Fix yamllint warnings
> > >
> > >  Documentation/devicetree/bindings/graph.txt  | 129 +---
> > >  Documentation/devicetree/bindings/graph.yaml | 199 +++
> > >  2 files changed, 200 insertions(+), 128 deletions(-)
> > >  create mode 100644 Documentation/devicetree/bindings/graph.yaml
> 
> [...]
> 
> > > diff --git a/Documentation/devicetree/bindings/graph.yaml 
> > > b/Documentation/devicetree/bindings/graph.yaml
> > > new file mode 100644
> > > index ..b56720c5a13e
> > > --- /dev/null
> > > +++ b/Documentation/devicetree/bindings/graph.yaml
> > > @@ -0,0 +1,199 @@
> > > +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> > > +%YAML 1.2
> > > +---
> > > +$id: http://devicetree.org/schemas/graph.yaml#
> > > +$schema: http://devicetree.org/meta-schemas/core.yaml#
> > > +
> > > +title: Common bindings for device graphs
> > > +
> > > +description: |
> > > +  The hierarchical organisation of the device tree is well suited to 
> > > describe
> > > +  control flow to devices, but there can be more complex connections 
> > > between
> > > +  devices that work together to form a logical compound device, 
> > > following an
> > > +  arbitrarily complex graph.
> > > +  There already is a simple directed graph between devices tree nodes 
> > > using
> > > +  phandle properties pointing to other nodes to describe connections that
> > > +  can not be inferred from device tree parent-child relationships. The 
> > > device
> > > +  tree graph bindings described herein abstract more complex devices 
> > > that can
> > > +  have multiple specifiable ports, each of which can be linked to one or 
> > > more
> > > +  ports of other devices.
> > > +
> > > +  These common bindings do not contain any information about the 
> > > direction or
> > > +  type of the connections, they just map their existence. Specific 
> > > properties
> > > +  may be described by specialized bindings depending on the type of 
> > > connection.
> > > +
> > > +  To see how this binding applies to video pipelines, for example, see
> > > +  Documentation/devicetree/bindings/media/video-interfaces.txt.
> > > +  Here the ports describe data interfaces, and the links between them are
> > > +  the connecting data buses. A single port with multiple connections can
> > > +  correspond to multiple devices being connected to the same physical 
> > > bus.
> > > +
> > > +maintainers:
> > > +  - Philipp Zabel 
> > > +
> > > +select: false
> > > +
> > > +properties:
> > > +  port:
> > > +type: object
> > > +description:
> > > +  If there is more than one endpoint node or 'reg' property present 
> > > in
> > > +  endpoint nodes then '#address-cells' and '#size-cells' properties 
> > > are
&g

Re: [PATCH v3 3/3] dt-bindings: panel: common: Add reference to graph schema

2020-11-11 Thread Laurent Pinchart
Hi Rob,

Thank you for the patch.

On Mon, Nov 02, 2020 at 02:36:56PM -0600, Rob Herring wrote:
> Now that we have a graph schema, reference it from the common panel
> schema.
> 
> Cc: Thierry Reding 
> Cc: Sam Ravnborg 
> Cc: Laurent Pinchart 
> Signed-off-by: Rob Herring 

Reviewed-by: Laurent Pinchart 

> ---
> v3: new patch
> 
>  .../devicetree/bindings/display/panel/panel-common.yaml| 7 +++
>  1 file changed, 3 insertions(+), 4 deletions(-)
> 
> diff --git 
> a/Documentation/devicetree/bindings/display/panel/panel-common.yaml 
> b/Documentation/devicetree/bindings/display/panel/panel-common.yaml
> index cd6dc5461721..a3a72c574213 100644
> --- a/Documentation/devicetree/bindings/display/panel/panel-common.yaml
> +++ b/Documentation/devicetree/bindings/display/panel/panel-common.yaml
> @@ -68,16 +68,15 @@ properties:
> 
># Connectivity
>port:
> -type: object
> +$ref: /schemas/graph.yaml#/properties/port
> 
>ports:
> -type: object
> +$ref: /schemas/graph.yaml#/properties/ports
>  description:
>Panels receive video data through one or multiple connections. While
>the nature of those connections is specific to the panel type, the
>connectivity is expressed in a standard fashion using ports as 
> specified
> -  in the device graph bindings defined in
> -  Documentation/devicetree/bindings/graph.txt.
> +  in the device graph bindings.
> 
>ddc-i2c-bus:
>  $ref: /schemas/types.yaml#/definitions/phandle

-- 
Regards,

Laurent Pinchart


<    1   2   3   4   5   6   7   8   9   10   >