Re: [PATCH] v4l-ioctl: Fix typo on v4l_print_frmsizeenum

2017-09-12 Thread Laurent Pinchart
Hi Ricardo,

Thank you for the patch.

On Friday, 8 September 2017 18:47:10 EEST Ricardo Ribalda Delgado wrote:
> max_width and max_height are swap with step_width and step_height.
> 
> Signed-off-by: Ricardo Ribalda Delgado 
> ---
> 
> Since that this bug has been here for ever. I do not know if we should
> notify stable or not
> 
> I have also cut the lines to respect the 80 char limit
> 
>  drivers/media/v4l2-core/v4l2-ioctl.c | 9 ++---
>  1 file changed, 6 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/media/v4l2-core/v4l2-ioctl.c
> b/drivers/media/v4l2-core/v4l2-ioctl.c index b60a6b0841d1..79614992ee21
> 100644
> --- a/drivers/media/v4l2-core/v4l2-ioctl.c
> +++ b/drivers/media/v4l2-core/v4l2-ioctl.c
> @@ -730,9 +730,12 @@ static void v4l_print_frmsizeenum(const void *arg, bool
> write_only) break;
>   case V4L2_FRMSIZE_TYPE_STEPWISE:
>   pr_cont(", min=%ux%u, max=%ux%u, step=%ux%u\n",
> - p->stepwise.min_width,  p->stepwise.min_height,
> - p->stepwise.step_width, p->stepwise.step_height,
> - p->stepwise.max_width,  p->stepwise.max_height);
> + p->stepwise.min_width,
> + p->stepwise.min_height,
> + p->stepwise.max_width,
> + p->stepwise.max_height,
> + p->stepwise.step_width,
> + p->stepwise.step_height);

If you fix the indentation as well (aligning p-> right after the '(') you 
could keep two arguments per line :-)

>   break;
>   case V4L2_FRMSIZE_TYPE_CONTINUOUS:
>   /* fall through */


-- 
Regards,

Laurent Pinchart



cron job: media_tree daily build: WARNINGS

2017-09-12 Thread Hans Verkuil
This message is generated daily by a cron job that builds media_tree for
the kernels and architectures in the list below.

Results of the daily build of media_tree:

date:   Wed Sep 13 05:00:26 CEST 2017
media-tree git hash:1efdf1776e2253b77413c997bed862410e4b6aaf
media_build git hash:   bbd9f669f0da6705fe44aff89281c0d6e7bfd73e
v4l-utils git hash: 019d01f3fa2cd34376211b0223c2aa7221670334
gcc version:i686-linux-gcc (GCC) 7.1.0
sparse version: v0.5.0
smatch version: v0.5.0-3553-g78b2ea6
host hardware:  x86_64
host os:4.12.0-164

linux-git-arm-at91: OK
linux-git-arm-davinci: OK
linux-git-arm-multi: OK
linux-git-arm-pxa: OK
linux-git-arm-stm32: OK
linux-git-blackfin-bf561: OK
linux-git-i686: OK
linux-git-m32r: OK
linux-git-mips: OK
linux-git-powerpc64: OK
linux-git-sh: OK
linux-git-x86_64: OK
linux-2.6.36.4-i686: WARNINGS
linux-2.6.37.6-i686: WARNINGS
linux-2.6.38.8-i686: WARNINGS
linux-2.6.39.4-i686: WARNINGS
linux-3.0.60-i686: WARNINGS
linux-3.1.10-i686: WARNINGS
linux-3.2.37-i686: WARNINGS
linux-3.3.8-i686: WARNINGS
linux-3.4.27-i686: WARNINGS
linux-3.5.7-i686: WARNINGS
linux-3.6.11-i686: WARNINGS
linux-3.7.4-i686: WARNINGS
linux-3.8-i686: WARNINGS
linux-3.9.2-i686: WARNINGS
linux-3.10.1-i686: WARNINGS
linux-3.11.1-i686: WARNINGS
linux-3.12.67-i686: WARNINGS
linux-3.13.11-i686: WARNINGS
linux-3.14.9-i686: WARNINGS
linux-3.15.2-i686: WARNINGS
linux-3.16.7-i686: WARNINGS
linux-3.17.8-i686: WARNINGS
linux-3.18.7-i686: WARNINGS
linux-3.19-i686: WARNINGS
linux-4.0.9-i686: WARNINGS
linux-4.1.33-i686: WARNINGS
linux-4.2.8-i686: WARNINGS
linux-4.3.6-i686: WARNINGS
linux-4.4.22-i686: WARNINGS
linux-4.5.7-i686: WARNINGS
linux-4.6.7-i686: WARNINGS
linux-4.7.5-i686: WARNINGS
linux-4.8-i686: OK
linux-4.9.26-i686: OK
linux-4.10.14-i686: OK
linux-4.11-i686: OK
linux-4.12.1-i686: OK
linux-4.13-i686: OK
linux-2.6.36.4-x86_64: WARNINGS
linux-2.6.37.6-x86_64: WARNINGS
linux-2.6.38.8-x86_64: WARNINGS
linux-2.6.39.4-x86_64: WARNINGS
linux-3.0.60-x86_64: WARNINGS
linux-3.1.10-x86_64: WARNINGS
linux-3.2.37-x86_64: WARNINGS
linux-3.3.8-x86_64: WARNINGS
linux-3.4.27-x86_64: WARNINGS
linux-3.5.7-x86_64: WARNINGS
linux-3.6.11-x86_64: WARNINGS
linux-3.7.4-x86_64: WARNINGS
linux-3.8-x86_64: WARNINGS
linux-3.9.2-x86_64: WARNINGS
linux-3.10.1-x86_64: WARNINGS
linux-3.11.1-x86_64: WARNINGS
linux-3.12.67-x86_64: WARNINGS
linux-3.13.11-x86_64: WARNINGS
linux-3.14.9-x86_64: WARNINGS
linux-3.15.2-x86_64: WARNINGS
linux-3.16.7-x86_64: WARNINGS
linux-3.17.8-x86_64: WARNINGS
linux-3.18.7-x86_64: WARNINGS
linux-3.19-x86_64: WARNINGS
linux-4.0.9-x86_64: WARNINGS
linux-4.1.33-x86_64: WARNINGS
linux-4.2.8-x86_64: WARNINGS
linux-4.3.6-x86_64: WARNINGS
linux-4.4.22-x86_64: WARNINGS
linux-4.5.7-x86_64: WARNINGS
linux-4.6.7-x86_64: WARNINGS
linux-4.7.5-x86_64: WARNINGS
linux-4.8-x86_64: WARNINGS
linux-4.9.26-x86_64: WARNINGS
linux-4.10.14-x86_64: WARNINGS
linux-4.11-x86_64: WARNINGS
linux-4.12.1-x86_64: WARNINGS
linux-4.13-x86_64: OK
apps: WARNINGS
spec-git: OK

Detailed results are available here:

http://www.xs4all.nl/~hverkuil/logs/Wednesday.log

Full logs are available here:

http://www.xs4all.nl/~hverkuil/logs/Wednesday.tar.bz2

The Media Infrastructure API from this daily build is here:

http://www.xs4all.nl/~hverkuil/spec/index.html


Re: [PATCH v3 4/6] [media] exynos-gsc: Add hardware rotation limits

2017-09-12 Thread Hoegeun Kwon

Hi Sylwester,

On 09/11/2017 06:35 PM, Sylwester Nawrocki wrote:

On 09/08/2017 08:02 AM, Hoegeun Kwon wrote:

The hardware rotation limits of gsc depends on SOC (Exynos
5250/5420/5433). Distinguish them and add them to the driver data.

Signed-off-by: Hoegeun Kwon 
---
  drivers/media/platform/exynos-gsc/gsc-core.c | 96 


  1 file changed, 83 insertions(+), 13 deletions(-)

diff --git a/drivers/media/platform/exynos-gsc/gsc-core.c 
b/drivers/media/platform/exynos-gsc/gsc-core.c

index 4380150..8f8636e 100644
--- a/drivers/media/platform/exynos-gsc/gsc-core.c
+++ b/drivers/media/platform/exynos-gsc/gsc-core.c
@@ -943,7 +943,37 @@ static irqreturn_t gsc_irq_handler(int irq, void 
*priv)

  return IRQ_HANDLED;
  }
  -static struct gsc_pix_max gsc_v_100_max = {
+static struct gsc_pix_max gsc_v_5250_max = {
+.org_scaler_bypass_w= 8192,
+.org_scaler_bypass_h= 8192,
+.org_scaler_input_w= 4800,
+.org_scaler_input_h= 3344,
+.real_rot_dis_w= 4800,
+.real_rot_dis_h= 3344,
+.real_rot_en_w= 2016,
+.real_rot_en_h= 2016,
+.target_rot_dis_w= 4800,
+.target_rot_dis_h= 3344,
+.target_rot_en_w= 2016,
+.target_rot_en_h= 2016,
+};
+
+static struct gsc_pix_max gsc_v_5420_max = {
+.org_scaler_bypass_w= 8192,
+.org_scaler_bypass_h= 8192,
+.org_scaler_input_w= 4800,
+.org_scaler_input_h= 3344,
+.real_rot_dis_w= 4800,
+.real_rot_dis_h= 3344,
+.real_rot_en_w= 2048,
+.real_rot_en_h= 2048,
+.target_rot_dis_w= 4800,
+.target_rot_dis_h= 3344,
+.target_rot_en_w= 2016,
+.target_rot_en_h= 2016,
+};
+
+static struct gsc_pix_max gsc_v_5433_max = {
  .org_scaler_bypass_w= 8192,
  .org_scaler_bypass_h= 8192,
  .org_scaler_input_w= 4800,
@@ -979,8 +1009,8 @@ static irqreturn_t gsc_irq_handler(int irq, void 
*priv)

  .target_h= 2,  /* yuv420 : 2, others : 1 */
  };
  -static struct gsc_variant gsc_v_100_variant = {
-.pix_max= &gsc_v_100_max,
+static struct gsc_variant gsc_v_5250_variant = {
+.pix_max= &gsc_v_5250_max,
  .pix_min= &gsc_v_100_min,
  .pix_align= &gsc_v_100_align,
  .in_buf_cnt= 32,
@@ -992,12 +1022,48 @@ static irqreturn_t gsc_irq_handler(int irq, 
void *priv)

  .local_sc_down= 2,
  };
  -static struct gsc_driverdata gsc_v_100_drvdata = {
+static struct gsc_variant gsc_v_5420_variant = {
+.pix_max= &gsc_v_5420_max,
+.pix_min= &gsc_v_100_min,
+.pix_align= &gsc_v_100_align,
+.in_buf_cnt= 32,
+.out_buf_cnt= 32,
+.sc_up_max= 8,
+.sc_down_max= 16,
+.poly_sc_down_max= 4,
+.pre_sc_down_max= 4,
+.local_sc_down= 2,
+};
+
+static struct gsc_variant gsc_v_5433_variant = {
+.pix_max= &gsc_v_5433_max,
+.pix_min= &gsc_v_100_min,
+.pix_align= &gsc_v_100_align,
+.in_buf_cnt= 32,
+.out_buf_cnt= 32,
+.sc_up_max= 8,
+.sc_down_max= 16,
+.poly_sc_down_max= 4,
+.pre_sc_down_max= 4,
+.local_sc_down= 2,
+};
+
+static struct gsc_driverdata gsc_v_5250_drvdata = {
  .variant = {
-[0] = &gsc_v_100_variant,
-[1] = &gsc_v_100_variant,
-[2] = &gsc_v_100_variant,
-[3] = &gsc_v_100_variant,
+[0] = &gsc_v_5250_variant,
+[1] = &gsc_v_5250_variant,
+[2] = &gsc_v_5250_variant,
+[3] = &gsc_v_5250_variant,
+},
+.num_entities = 4,
+.clk_names = { "gscl" },
+.num_clocks = 1,
+};
+
+static struct gsc_driverdata gsc_v_5420_drvdata = {
+.variant = {
+[0] = &gsc_v_5420_variant,
+[1] = &gsc_v_5420_variant,
  },
  .num_entities = 4,
  .clk_names = { "gscl" },
@@ -1006,9 +1072,9 @@ static irqreturn_t gsc_irq_handler(int irq, 
void *priv)

static struct gsc_driverdata gsc_5433_drvdata = {
  .variant = {
-[0] = &gsc_v_100_variant,
-[1] = &gsc_v_100_variant,
-[2] = &gsc_v_100_variant,
+[0] = &gsc_v_5433_variant,
+[1] = &gsc_v_5433_variant,
+[2] = &gsc_v_5433_variant,
  },
  .num_entities = 3,
  .clk_names = { "pclk", "aclk", "aclk_xiu", "aclk_gsclbend" },
@@ -1017,8 +1083,12 @@ static irqreturn_t gsc_irq_handler(int irq, 
void *priv)

static const struct of_device_id exynos_gsc_match[] = {
  {
-.compatible = "samsung,exynos5-gsc",
-.data = &gsc_v_100_drvdata,


Can you keep the "samsung,exynos5-gsc" entry with the gsc_v_5250_variant
data, so that it can work with "samsung,exynos5-gsc" compatible in DT
on both exynos5250 and exynos5420 SoCs?



Thank you for your question.

Exynos 5250 and 5420 have different hardware rotation limits.
Exynos 5250 is '.real_rot_en_w/h = 2016' and 5420 is '.real_rot

Re: [PATCH v2 3/8] v4l: vsp1: Convert display lists to use new fragment pool

2017-09-12 Thread Laurent Pinchart
Hi Kieran,

On Monday, 11 September 2017 23:27:39 EEST Kieran Bingham wrote:
> On 17/08/17 13:13, Laurent Pinchart wrote:
> > On Monday 14 Aug 2017 16:13:26 Kieran Bingham wrote:
> >> Adapt the dl->body0 object to use an object from the fragment pool.
> >> This greatly reduces the pressure on the TLB for IPMMU use cases, as
> >> all of the lists use a single allocation for the main body.
> >> 
> >> The CLU and LUT objects pre-allocate a pool containing two bodies,
> >> allowing a userspace update before the hardware has committed a previous
> >> set of tables.
> > 
> > I think you'll need three bodies, one for the DL queued to the hardware,
> > one for the pending DL and one for the new DL needed when you update the
> > LUT/CLU. Given that the VSP test suite hasn't caught this problem, we
> > also need a new test :-)
> > 
> >> Fragments are no longer 'freed' in interrupt context, but instead
> >> released back to their respective pools.  This allows us to remove the
> >> garbage collector in the DLM.
> >> 
> >> Signed-off-by: Kieran Bingham 
> >> 
> >> ---
> >> 
> >> v2:
> >>  - Use dl->body0->max_entries to determine header offset, instead of the
> >>global constant VSP1_DL_NUM_ENTRIES which is incorrect.
> >>  
> >>  - squash updates for LUT, CLU, and fragment cleanup into single patch.
> >>(Not fully bisectable when separated)
> >> 
> >> ---
> >> 
> >>  drivers/media/platform/vsp1/vsp1_clu.c |  22 ++-
> >>  drivers/media/platform/vsp1/vsp1_clu.h |   1 +-
> >>  drivers/media/platform/vsp1/vsp1_dl.c  | 223 +-
> >>  drivers/media/platform/vsp1/vsp1_dl.h  |   3 +-
> >>  drivers/media/platform/vsp1/vsp1_lut.c |  23 ++-
> >>  drivers/media/platform/vsp1/vsp1_lut.h |   1 +-
> >>  6 files changed, 90 insertions(+), 183 deletions(-)
> > 
> > This is a nice diffstat, but only if you add kerneldoc for the new
> > functions introduced in patch 2/8, otherwise the overall documentation
> > diffstat looks bad :-)

[snip]

> >> diff --git a/drivers/media/platform/vsp1/vsp1_dl.c
> >> b/drivers/media/platform/vsp1/vsp1_dl.c index aab9dd6ec0eb..6ffdc3549283
> >> 100644
> >> --- a/drivers/media/platform/vsp1/vsp1_dl.c
> >> +++ b/drivers/media/platform/vsp1/vsp1_dl.c

[snip]

> >>  static void vsp1_dl_list_free(struct vsp1_dl_list *dl)
> >>  {
> >> 
> >> -  vsp1_dl_body_cleanup(&dl->body0);
> >> -  list_splice_init(&dl->fragments, &dl->dlm->gc_fragments);
> >> +  vsp1_dl_fragment_put(dl->body0);
> >> +  vsp1_dl_list_fragments_free(dl);
> > 
> > I wonder whether the second line is actually needed. vsp1_dl_list_free()
> > is called from vsp1_dlm_destroy() for every entry in the dlm->free list. A
> > DL can only be put in that list by vsp1_dlm_create() or
> > __vsp1_dl_list_put(). The former creates lists with no fragment, while
> > the latter calls vsp1_dl_list_fragments_free() already.
> > 
> > If you're not entirely sure you could add a WARN_ON(!list_empty(&dl-
> > >fragments)) and run the test suite. A comment explaining why the
> > fragments list should already be empty here would be useful too.
> 
> You may be right here, but would you object to leaving it in ?
> 
> Isn't it correct to ensure that the list is completely cleaned up on
> release?
> 
> Furthermore - I would anticipate that in the future - 'body0' could be
> removed, (becoming a fragment) and thus this line would then be required.
> 
> ## /where 's/fragments/bodies/g' applies to the above text. ##

I'm fine with that for now.

> >> +
> >> 
> >>kfree(dl);
> >>  }

-- 
Regards,

Laurent Pinchart



Re: [PATCH v2 2/8] v4l: vsp1: Provide a fragment pool

2017-09-12 Thread Laurent Pinchart
Hi Kieran,

On Monday, 11 September 2017 23:30:25 EEST Kieran Bingham wrote:
> On 17/08/17 13:13, Laurent Pinchart wrote:
> > On Monday 14 Aug 2017 16:13:25 Kieran Bingham wrote:
> >> Each display list allocates a body to store register values in a dma
> >> accessible buffer from a dma_alloc_wc() allocation. Each of these
> >> results in an entry in the TLB, and a large number of display list
> >> allocations adds pressure to this resource.
> >> 
> >> Reduce TLB pressure on the IPMMUs by allocating multiple display list
> >> bodies in a single allocation, and providing these to the display list
> >> through a 'fragment pool'. A pool can be allocated by the display list
> >> manager or entities which require their own body allocations.
> >> 
> >> Signed-off-by: Kieran Bingham 
> >> 
> >> ---
> >> 
> >> v2:
> >>  - assign dlb->dma correctly
> >> 
> >> ---
> >> 
> >>  drivers/media/platform/vsp1/vsp1_dl.c | 129 +++-
> >>  drivers/media/platform/vsp1/vsp1_dl.h |   8 ++-
> >>  2 files changed, 137 insertions(+)
> >> 
> >> diff --git a/drivers/media/platform/vsp1/vsp1_dl.c
> >> b/drivers/media/platform/vsp1/vsp1_dl.c index cb4625ae13c2..aab9dd6ec0eb
> >> 100644
> >> --- a/drivers/media/platform/vsp1/vsp1_dl.c
> >> +++ b/drivers/media/platform/vsp1/vsp1_dl.c

[snip]

> >>  /*
> >> + * Fragment pool's reduce the pressure on the iommu TLB by allocating a
> >> single
> >> + * large area of DMA memory and allocating it as a pool of fragment
> >> bodies
> >> + */
> > 
> > Could you document non-static function using kerneldoc ? Parameters to
> > this function would benefit from some documentation. I'd also like to see
> > the fragment get/put functions documented, as you remove existing
> > kerneldoc for the alloc/free existing functions in patch 3/8.
> 
> Ah yes of course.
> 
> >> +struct vsp1_dl_fragment_pool *
> >> +vsp1_dl_fragment_pool_alloc(struct vsp1_device *vsp1, unsigned int qty,
> > 
> > I think I would name this function vsp1_dl_fragment_pool_create(), as it
> > does more than just allocating memory. Similarly I'd call the free
> > function vsp1_dl_fragment_pool_destroy().
> 
> That sounds reasonable. Done.
> 
> > qty is a bit vague, I'd rename it to num_fragments.
> 
> Ok with me.
> 
> >> +  unsigned int num_entries, size_t extra_size)
> >> +{
> >> +  struct vsp1_dl_fragment_pool *pool;
> >> +  size_t dlb_size;
> >> +  unsigned int i;
> >> +
> >> +  pool = kzalloc(sizeof(*pool), GFP_KERNEL);
> >> +  if (!pool)
> >> +  return NULL;
> >> +
> >> +  pool->vsp1 = vsp1;
> >> +
> >> +  dlb_size = num_entries * sizeof(struct vsp1_dl_entry) + extra_size;
> > 
> > extra_size is only used by vsp1_dlm_create(), to allocate extra memory for
> > the display list header. We need one header per display list, not per
> > display list body.
> 
> Good catch, that will take a little bit of reworking.

I didn't propose a fix for this as I wasn't sure how to fix it properly. I 
thus won't complain too loudly if you can't fix it either and waste a bit of 
memory :-) But in that case please add a comment to explain what's going on.

> >> +  pool->size = dlb_size * qty;
> >> +
> >> +  pool->bodies = kcalloc(qty, sizeof(*pool->bodies), GFP_KERNEL);
> >> +  if (!pool->bodies) {
> >> +  kfree(pool);
> >> +  return NULL;
> >> +  }
> >> +
> >> +  pool->mem = dma_alloc_wc(vsp1->bus_master, pool->size, &pool->dma,
> >> +  GFP_KERNEL);
> > 
> > This is a weird indentation.
> 
> I know! - Not sure how that slipped by :)
> 
> >> +  if (!pool->mem) {
> >> +  kfree(pool->bodies);
> >> +  kfree(pool);
> >> +  return NULL;
> >> +  }
> >> +
> >> +  spin_lock_init(&pool->lock);
> >> +  INIT_LIST_HEAD(&pool->free);
> >> +
> >> +  for (i = 0; i < qty; ++i) {
> >> +  struct vsp1_dl_body *dlb = &pool->bodies[i];
> >> +
> >> +  dlb->pool = pool;
> >> +  dlb->max_entries = num_entries;
> >> +
> >> +  dlb->dma = pool->dma + i * dlb_size;
> >> +  dlb->entries = pool->mem + i * dlb_size;
> >> +
> >> +  list_add_tail(&dlb->free, &pool->free);
> >> +  }
> >> +
> >> +  return pool;
> >> +}
> >> +
> >> +void vsp1_dl_fragment_pool_free(struct vsp1_dl_fragment_pool *pool)
> >> +{
> >> +  if (!pool)
> >> +  return;
> > 
> > Can this happen ?
> 
> I was mirroring 'kfree()' support here ... such that error paths can be
> simple.
> 
> Would you prefer that it's required to be valid (non-null) pointer?
> 
> Actually - I think it is better to leave this for now - as we now call this
> function from the .destroy() entity functions ...

It was a genuine question :-) We have more control over the 
vsp1_dl_fragment_pool_free() callers as the function is internal to the 
driver. If we have real use cases for pool being NULL then let's keep the 
check.

> >> +
> >> +  if (pool->mem)
> >> +  dma_free_wc(pool->vsp1->bus_master, pool->size, pool->mem,
> >> +  pool->d

Re: as3645a flash userland interface

2017-09-12 Thread Pavel Machek
On Tue 2017-09-12 20:53:33, Jacek Anaszewski wrote:
> Hi Pavel,
> 
> On 09/12/2017 12:36 PM, Pavel Machek wrote:
> > Hi!
> > 
> > There were some changes to as3645a flash controller. Before we have
> > stable interface we have to keep forever I want to ask:
> 
> Note that we have already two LED flash class drivers - leds-max77693
> and leds-aat1290. They have been present in mainline for over two years
> now.

Well.. that's ok. No change there is neccessary.

> > What directory are the flash controls in?
> > 
> > /sys/class/leds/led-controller:flash ?
> > 
> > Could we arrange for something less generic, like
> > 
> > /sys/class/leds/main-camera:flash ?
> 
> I'd rather avoid overcomplicating this. LED class device name pattern
> is well defined to devicename:colour:function
> (see Documentation/leds/leds-class.txt, "LED Device Naming" section).
> 
> In this case "flash" in place of the "function" segment makes the
> things clear enough I suppose.

It does not.

Phones usually have two cameras, front and back, and these days both
cameras have their flash.

And poor userspace flashlight application can not know if as3645
drivers front LED or back LED. Thus, I'd set devicename to
front-camera or main-camera -- because that's what it is associated
with. Userspace does not care what hardware drives the LED, but needs
to know if it is front or back camera.

If LEDs control keyboard backlight, I'd expect the LED name to be
"keyboard::backlight", not "i2c-0020-adp1643::backlight".

Thanks,
Pavel
-- 
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) 
http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html


signature.asc
Description: Digital signature


Re: [media] s5p-mfc: Adjust a null pointer check in four functions

2017-09-12 Thread SF Markus Elfring
> Generating patch is only part of the story,

I can follow this view in principle.


> it seems the patch is not sent properly

I got an other impression.


> and tags which should be in SMTP header end up in the message body.

I agree that extra message fields were presented by the git software for
a reason.
You might have got other opinions about the original reason (than me).


> I think there would not be such issues if you have used git
> format-patch + git send-email.

I have got also doubts about your corresponding expectations when you
would find
the proposed commit message itself acceptable (besides the small source
code changes).


> I normally do amend things like this while applying,

That is interesting.


> I will do that this time as well.

Such an action can also be nice.


> It's already too much time wasted for such a dubious patch.

A bit of time is needed to resolve a temporary disagreement.

Regards,
Markus


[PATCH] [media] s3c-camif: fix out-of-bounds array access

2017-09-12 Thread Arnd Bergmann
While experimenting with older compiler versions, I ran
into a warning that no longer shows up on gcc-4.8 or newer:

drivers/media/platform/s3c-camif/camif-capture.c: In function 
'__camif_subdev_try_format':
drivers/media/platform/s3c-camif/camif-capture.c:1265:25: error: array 
subscript is below array bounds

This is an off-by-one bug, leading to an access before the start of the
array, while newer compilers silently assume this undefined behavior
cannot happen and leave the loop at index 0 if no other entry matches.

Since the code is not only wrong, but also has no effect besides the
out-of-bounds access, this patch just removes it.

I found an existing gcc bug for it and added a reduced version
of the function there.

Link: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69249#c3
Fixes: babde1c243b2 ("[media] V4L: Add driver for S3C24XX/S3C64XX SoC series 
camera interface")
Signed-off-by: Arnd Bergmann 
---
 drivers/media/platform/s3c-camif/camif-capture.c | 7 ---
 1 file changed, 7 deletions(-)

diff --git a/drivers/media/platform/s3c-camif/camif-capture.c 
b/drivers/media/platform/s3c-camif/camif-capture.c
index 25c7a7d42292..c6921f6a5a6a 100644
--- a/drivers/media/platform/s3c-camif/camif-capture.c
+++ b/drivers/media/platform/s3c-camif/camif-capture.c
@@ -1256,17 +1256,10 @@ static void __camif_subdev_try_format(struct camif_dev 
*camif,
 {
const struct s3c_camif_variant *variant = camif->variant;
const struct vp_pix_limits *pix_lim;
-   int i = ARRAY_SIZE(camif_mbus_formats);
 
/* FIXME: constraints against codec or preview path ? */
pix_lim = &variant->vp_pix_limits[VP_CODEC];
 
-   while (i-- >= 0)
-   if (camif_mbus_formats[i] == mf->code)
-   break;
-
-   mf->code = camif_mbus_formats[i];
-
if (pad == CAMIF_SD_PAD_SINK) {
v4l_bound_align_image(&mf->width, 8, CAMIF_MAX_PIX_WIDTH,
  ffs(pix_lim->out_width_align) - 1,
-- 
2.9.0



Re: [PATCH v2 5/8] v4l: vsp1: Refactor display list configure operations

2017-09-12 Thread Laurent Pinchart
Hi Kieran,

On Tuesday, 12 September 2017 00:16:50 EEST Kieran Bingham wrote:
> On 17/08/17 19:13, Laurent Pinchart wrote:
> > On Monday 14 Aug 2017 16:13:28 Kieran Bingham wrote:
> >> The entities provide a single .configure operation which configures the
> >> object into the target display list, based on the vsp1_entity_params
> >> selection.
> >> 
> >> This restricts us to a single function prototype for both static
> >> configuration (the pre-stream INIT stage) and the dynamic runtime stages
> >> for both each frame - and each partition therein.
> >> 
> >> Split the configure function into two parts, '.prepare()' and
> >> '.configure()', merging both the VSP1_ENTITY_PARAMS_RUNTIME and
> >> VSP1_ENTITY_PARAMS_PARTITION stages into a single call through the
> >> .configure(). The configuration for individual partitions is handled by
> >> passing the partition number to the configure call, and processing any
> >> runtime stage actions on the first partition only.
> >> 
> >> Signed-off-by: Kieran Bingham 
> >> ---
> >> 
> >>  drivers/media/platform/vsp1/vsp1_bru.c|  12 +-
> >>  drivers/media/platform/vsp1/vsp1_clu.c|  43 +--
> >>  drivers/media/platform/vsp1/vsp1_drm.c|  11 +-
> >>  drivers/media/platform/vsp1/vsp1_entity.c |  15 +-
> >>  drivers/media/platform/vsp1/vsp1_entity.h |  27 +--
> >>  drivers/media/platform/vsp1/vsp1_hgo.c|  12 +-
> >>  drivers/media/platform/vsp1/vsp1_hgt.c|  12 +-
> >>  drivers/media/platform/vsp1/vsp1_hsit.c   |  12 +-
> >>  drivers/media/platform/vsp1/vsp1_lif.c|  12 +-
> >>  drivers/media/platform/vsp1/vsp1_lut.c|  24 +-
> >>  drivers/media/platform/vsp1/vsp1_rpf.c| 162 ++---
> >>  drivers/media/platform/vsp1/vsp1_sru.c|  12 +-
> >>  drivers/media/platform/vsp1/vsp1_uds.c|  55 ++--
> >>  drivers/media/platform/vsp1/vsp1_video.c  |  24 +--
> >>  drivers/media/platform/vsp1/vsp1_wpf.c| 297 ---
> >>  15 files changed, 359 insertions(+), 371 deletions(-)
> > 
> > [snip]
> > 
> >> diff --git a/drivers/media/platform/vsp1/vsp1_clu.c
> >> b/drivers/media/platform/vsp1/vsp1_clu.c index 175717018e11..5f65ce3ad97f
> >> 100644
> >> --- a/drivers/media/platform/vsp1/vsp1_clu.c
> >> +++ b/drivers/media/platform/vsp1/vsp1_clu.c
> >> @@ -213,37 +213,37 @@ static const struct v4l2_subdev_ops clu_ops = {
> >> 
> >>  /*
> >>  ---
> >>  -
> >>  
> >>   * VSP1 Entity Operations
> >>   */
> >> 
> >> +static void clu_prepare(struct vsp1_entity *entity,
> >> +  struct vsp1_pipeline *pipe,
> >> +  struct vsp1_dl_list *dl)
> >> +{
> >> +  struct vsp1_clu *clu = to_clu(&entity->subdev);
> >> +
> >> +  /*
> >> +   * The format can't be changed during streaming, only verify it
> >> +   * at setup time and store the information internally for future
> >> +   * runtime configuration calls.
> >> +   */
> > 
> > I know you're just moving the comment around, but let's fix it at the same
> > time. There's no verification here (and no "setup time" either). I'd write
> > it as
> > 
> > /*
> > 
> >  * The format can't be changed during streaming. Cache it internally
> >  * for future runtime configuration calls.
> >  */
> 
> I think I'm ok with that and I've updated the patch - but I'm not sure we
> are really caching the 'format' here, as much as the yuv_mode ...

Yes, it's the YUV mode we're caching, feel free to update the comment.

> I'll ponder ...
> 
> >> +  struct v4l2_mbus_framefmt *format;
> >> +
> >> +  format = vsp1_entity_get_pad_format(&clu->entity,
> >> +  clu->entity.config,
> >> +  CLU_PAD_SINK);
> >> +  clu->yuv_mode = format->code == MEDIA_BUS_FMT_AYUV8_1X32;
> >> +}
> > 
> > [snip]
> > 
> >> diff --git a/drivers/media/platform/vsp1/vsp1_entity.h
> >> b/drivers/media/platform/vsp1/vsp1_entity.h index
> >> 408602ebeb97..2f33e343ccc6 100644
> >> --- a/drivers/media/platform/vsp1/vsp1_entity.h
> >> +++ b/drivers/media/platform/vsp1/vsp1_entity.h
> > 
> > [snip]
> > 
> >> @@ -80,8 +68,10 @@ struct vsp1_route {
> >> 
> >>  /**
> >>  
> >>   * struct vsp1_entity_operations - Entity operations
> >>   * @destroy:  Destroy the entity.
> >> 
> >> - * @configure:Setup the hardware based on the entity state
> >> (pipeline, formats,
> >> - *selection rectangles, ...)
> >> + * @prepare:  Setup the initial hardware parameters for the stream
> >> (pipeline,
> >> + *formats)
> >> + * @configure:Configure the runtime parameters for each partition
> >> (rectangles,
> >> + *buffer addresses, ...)
> > 
> > Now moving to the bikeshedding territory, I'm not sure if prepare and
> > configure are the best names for those operations. I'd like to also point
> > out that we could go one step further by caching the partition-related
> > parameters too, in which case we would need a third operation (

Re: [PATCH v2 6/8] v4l: vsp1: Adapt entities to configure into a body

2017-09-12 Thread Laurent Pinchart
Hi Kieran,

On Tuesday, 12 September 2017 00:42:09 EEST Kieran Bingham wrote:
> On 17/08/17 18:58, Laurent Pinchart wrote:
> > On Monday 14 Aug 2017 16:13:29 Kieran Bingham wrote:
> >> Currently the entities store their configurations into a display list.
> >> Adapt this such that the code can be configured into a body fragment
> >> directly, allowing greater flexibility and control of the content.
> >> 
> >> All users of vsp1_dl_list_write() are removed in this process, thus it
> >> too is removed.
> >> 
> >> A helper, vsp1_dl_list_body() is provided to access the internal body0
> >> from the display list.
> >> 
> >> Signed-off-by: Kieran Bingham 
> >> ---
> >> 
> >>  drivers/media/platform/vsp1/vsp1_bru.c| 22 ++--
> >>  drivers/media/platform/vsp1/vsp1_clu.c| 22 ++--
> >>  drivers/media/platform/vsp1/vsp1_dl.c | 12 ++-
> >>  drivers/media/platform/vsp1/vsp1_dl.h |  2 +-
> >>  drivers/media/platform/vsp1/vsp1_drm.c| 14 +---
> >>  drivers/media/platform/vsp1/vsp1_entity.c | 16 -
> >>  drivers/media/platform/vsp1/vsp1_entity.h | 12 ---
> >>  drivers/media/platform/vsp1/vsp1_hgo.c| 16 -
> >>  drivers/media/platform/vsp1/vsp1_hgt.c| 18 +-
> >>  drivers/media/platform/vsp1/vsp1_hsit.c   | 10 +++---
> >>  drivers/media/platform/vsp1/vsp1_lif.c| 13 +++
> >>  drivers/media/platform/vsp1/vsp1_lut.c| 21 ++--
> >>  drivers/media/platform/vsp1/vsp1_pipe.c   |  4 +-
> >>  drivers/media/platform/vsp1/vsp1_pipe.h   |  3 +-
> >>  drivers/media/platform/vsp1/vsp1_rpf.c| 43 +++-
> >>  drivers/media/platform/vsp1/vsp1_sru.c| 14 
> >>  drivers/media/platform/vsp1/vsp1_uds.c| 24 +++--
> >>  drivers/media/platform/vsp1/vsp1_uds.h|  2 +-
> >>  drivers/media/platform/vsp1/vsp1_video.c  | 11 --
> >>  drivers/media/platform/vsp1/vsp1_wpf.c| 42 ---
> >>  20 files changed, 168 insertions(+), 153 deletions(-)
> > 
> > This is quite intrusive, and it bothers me slightly that we need to pass
> > both the DL and the DLB to the configure function in order to add
> > fragments to the DL in the CLU and LUT modules. Wouldn't it be simpler to
> > add a pointer to the current body in the DL structure, and modify
> > vsp1_dl_list_write() to write to the current fragment ?
> 
> No doubt about it, 168+, 153- is certainly intrusive.
> 
> Yes, now I'm looking back at this, I think this does look like this part is
> not quite the right approach.
> 
> Which otherwise stalls the series until I have time to reconsider. I will
> likely repost the work I have done on the earlier patches, including the
> 's/fragment/body/g' changes and ready myself for a v4 which will contain the
> heavier reworks.

Fine with me. Could you make sure to mention the open issues in the cover 
letter ? I want to avoid commenting on them if you know already that you will 
rework them later.

-- 
Regards,

Laurent Pinchart



Re: [PATCH v3 2/2] v4l: cadence: Add Cadence MIPI-CSI2 RX driver

2017-09-12 Thread Benoit Parrot
Benoit Parrot  wrote on Tue [2017-Sep-12 13:23:39 -0500]:



> > +static int csi2rx_start(struct csi2rx_priv *csi2rx)
> > +{
> > +   unsigned int i;
> > +   u32 reg;
> > +   int ret;
> > +
> > +   /*
> > +* We're not the first users, there's no need to enable the
> > +* whole controller.
> > +*/
> > +   if (atomic_inc_return(&csi2rx->count) > 1)
> > +   return 0;
> > +
> > +   clk_prepare_enable(csi2rx->p_clk);
> > +
> > +   printk("%s %d\n", __func__, __LINE__);
> 
> Some left over debug...
> 
> > +
> > +   csi2rx_reset(csi2rx);
> > +
> > +   reg = csi2rx->num_lanes << 8;
> > +   for (i = 0; i < csi2rx->num_lanes; i++)
> > +   reg |= CSI2RX_STATIC_CFG_DLANE_MAP(i, csi2rx->lanes[i]);
> > +
> > +   writel(reg, csi2rx->base + CSI2RX_STATIC_CFG_REG);
> > +
> > +   ret = v4l2_subdev_call(csi2rx->source_subdev, video, s_stream, true);
> > +   if (ret)
> > +   return ret;
> > +
> > +   /*
> > +* Create a static mapping between the CSI virtual channels
> > +* and the output stream.
> > +*
> > +* This should be enhanced, but v4l2 lacks the support for
> > +* changing that mapping dynamically.
> > +*
> > +* We also cannot enable and disable independant streams here,
> > +* hence the reference counting.
> > +*/
> > +   for (i = 0; i < csi2rx->max_streams; i++) {
> > +   clk_prepare_enable(csi2rx->pixel_clk[i]);
> > +
> > +   writel(CSI2RX_STREAM_CFG_FIFO_MODE_LARGE_BUF,
> > +  csi2rx->base + CSI2RX_STREAM_CFG_REG(i));
> > +
> > +   writel(CSI2RX_STREAM_DATA_CFG_EN_VC_SELECT |
> > +  CSI2RX_STREAM_DATA_CFG_VC_SELECT(i),
> > +  csi2rx->base + CSI2RX_STREAM_DATA_CFG_REG(i));

I see here that we are setting the data_type to 0 (as we are not setting
it) so effectively capturing everything on the channel(s).
Will we be adding a method to select/filter specific data type?
For instance if we only want to grab YUV data in one stream and only
RGB24 in another. Of course that would not be possible here as is...

Benoit

> > +
> > +   writel(CSI2RX_STREAM_CTRL_START,
> > +  csi2rx->base + CSI2RX_STREAM_CTRL_REG(i));
> > +   }
> > +
> > +   clk_prepare_enable(csi2rx->sys_clk);
> > +
> > +   clk_disable_unprepare(csi2rx->p_clk);
> > +
> > +   return 0;
> > +}




Re: as3645a flash userland interface

2017-09-12 Thread Jacek Anaszewski
Hi Pavel,

On 09/12/2017 12:36 PM, Pavel Machek wrote:
> Hi!
> 
> There were some changes to as3645a flash controller. Before we have
> stable interface we have to keep forever I want to ask:

Note that we have already two LED flash class drivers - leds-max77693
and leds-aat1290. They have been present in mainline for over two years
now.

> What directory are the flash controls in?
> 
> /sys/class/leds/led-controller:flash ?
> 
> Could we arrange for something less generic, like
> 
> /sys/class/leds/main-camera:flash ?

I'd rather avoid overcomplicating this. LED class device name pattern
is well defined to devicename:colour:function
(see Documentation/leds/leds-class.txt, "LED Device Naming" section).

In this case "flash" in place of the "function" segment makes the
things clear enough I suppose.

-- 
Best regards,
Jacek Anaszewski


Re: [PATCH] media: dvb_frontend: only use kref after initialized

2017-09-12 Thread Laurent Pinchart
Hi Mauro,

Thank you for the patch.

On Tuesday, 12 September 2017 13:19:10 EEST Mauro Carvalho Chehab wrote:
> As reported by Laurent, when a DVB frontend need to register
> two drivers (e. g. a tuner and a demod), if the second driver
> fails to register (for example because it was not compiled),
> the error handling logic frees the frontend by calling
> dvb_frontend_detach(). That used to work fine, but changeset
> 1f862a68df24 ("[media] dvb_frontend: move kref to struct dvb_frontend")
> added a kref at struct dvb_frontend. So, now, instead of just
> freeing the data, the error handling do a kref_put().
> 
> That works fine only after dvb_register_frontend() succeeds.
> 
> While it would be possible to add a helper function that
> would be initializing earlier the kref, that would require
> changing every single DVB frontend on non-trivial ways, and
> would make frontends different than other drivers.
> 
> So, instead of doing that, let's focus on the real issue:
> only call kref_put() after kref_init(). That's easy to
> check, as, when the dvb frontend is successfuly registered,
> it will allocate its own private struct. So, if such
> struct is allocated, it means that it is safe to use
> kref_put(). If not, then nobody is using yet the frontend,
> and it is safe to just deallocate it.
> 
> Fixes: 1f862a68df24 ("[media] dvb_frontend: move kref to struct
> dvb_frontend") Reported-by: Laurent Pinchart
>  Signed-off-by: Mauro Carvalho
> Chehab 
> ---
> 
> Laurent,
> 
> Could you please check if this patch fixes the issue you noticed?

I can't as I don't have the device with me this week.

Reviewing the code, I think this is a hack. Now, if dvb_attach() goes away, I 
understand you might not want to change all old-style drivers to fix the issue 
I've reported, only to convert them to the new API later. However, API 
conversion seems to go very slow. In the end it's up to you whether you want 
to fix issues properly or hack around them, but pilin up hacks creates a 
technical debt that will bite you back sooner or latter (and definitely at the 
worst possible time).

>  drivers/media/dvb-core/dvb_frontend.c | 25 +
>  1 file changed, 21 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/media/dvb-core/dvb_frontend.c
> b/drivers/media/dvb-core/dvb_frontend.c index 2fcba1616168..9139d01ba7ed
> 100644
> --- a/drivers/media/dvb-core/dvb_frontend.c
> +++ b/drivers/media/dvb-core/dvb_frontend.c
> @@ -141,22 +141,39 @@ struct dvb_frontend_private {
>  static void dvb_frontend_invoke_release(struct dvb_frontend *fe,
>   void (*release)(struct dvb_frontend 
> *fe));
> 
> -static void dvb_frontend_free(struct kref *ref)
> +static void __dvb_frontend_free(struct dvb_frontend *fe)
>  {
> - struct dvb_frontend *fe =
> - container_of(ref, struct dvb_frontend, refcount);
>   struct dvb_frontend_private *fepriv = fe->frontend_priv;
> 
> + if (!fepriv)
> + return;
> +
>   dvb_free_device(fepriv->dvbdev);
> 
>   dvb_frontend_invoke_release(fe, fe->ops.release);
> 
>   kfree(fepriv);
> + fe->frontend_priv = NULL;
> +}
> +
> +static void dvb_frontend_free(struct kref *ref)
> +{
> + struct dvb_frontend *fe =
> + container_of(ref, struct dvb_frontend, refcount);
> +
> + __dvb_frontend_free(fe);
>  }
> 
>  static void dvb_frontend_put(struct dvb_frontend *fe)
>  {
> - kref_put(&fe->refcount, dvb_frontend_free);
> + /*
> +  * Check if the frontend was registered, as otherwise
> +  * kref was not initialized yet.
> +  */
> + if (fe->frontend_priv)
> + kref_put(&fe->refcount, dvb_frontend_free);
> + else
> + __dvb_frontend_free(fe);
>  }
> 
>  static void dvb_frontend_get(struct dvb_frontend *fe)


-- 
Regards,

Laurent Pinchart



Re: [PATCH v3 2/2] v4l: cadence: Add Cadence MIPI-CSI2 RX driver

2017-09-12 Thread Benoit Parrot
Maxime,

Thanks for the patch.

Maxime Ripard  wrote on Mon [2017-Sep-04 
15:03:35 +0200]:
> The Cadence CSI-2 RX Controller is an hardware block meant to be used as a
> bridge between a CSI-2 bus and pixel grabbers.
> 
> It supports operating with internal or external D-PHY, with up to 4 lanes,
> or without any D-PHY. The current code only supports the former case.
> 
> It also support dynamic mapping of the CSI-2 virtual channels to the
> associated pixel grabbers, but that isn't allowed at the moment either.
> 
> Signed-off-by: Maxime Ripard 
> ---
>  drivers/media/platform/Kconfig   |   1 +
>  drivers/media/platform/Makefile  |   2 +
>  drivers/media/platform/cadence/Kconfig   |  12 +
>  drivers/media/platform/cadence/Makefile  |   1 +
>  drivers/media/platform/cadence/cdns-csi2rx.c | 494 
> +++
>  5 files changed, 510 insertions(+)
>  create mode 100644 drivers/media/platform/cadence/Kconfig
>  create mode 100644 drivers/media/platform/cadence/Makefile
>  create mode 100644 drivers/media/platform/cadence/cdns-csi2rx.c
>



> diff --git a/drivers/media/platform/cadence/cdns-csi2rx.c 
> b/drivers/media/platform/cadence/cdns-csi2rx.c
> new file mode 100644
> index ..e662b1890bba
> --- /dev/null
> +++ b/drivers/media/platform/cadence/cdns-csi2rx.c
> @@ -0,0 +1,494 @@
> +/*
> + * Driver for Cadence MIPI-CSI2 RX Controller v1.3
> + *
> + * Copyright (C) 2017 Cadence Design Systems Inc.
> + *
> + * This program is free software; you can redistribute  it and/or modify it
> + * under  the terms of  the GNU General  Public License as published by the
> + * Free Software Foundation;  either version 2 of the  License, or (at your
> + * option) any later version.
> + */
> +
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +
> +#include 
> +#include 
> +#include 
> +#include 
> +
> +#define CSI2RX_DEVICE_CFG_REG0x000
> +
> +#define CSI2RX_SOFT_RESET_REG0x004
> +#define CSI2RX_SOFT_RESET_PROTOCOL   BIT(1)
> +#define CSI2RX_SOFT_RESET_FRONT  BIT(0)
> +
> +#define CSI2RX_STATIC_CFG_REG0x008
> +#define CSI2RX_STATIC_CFG_DLANE_MAP(llane, plane)((plane) << (16 + 
> (llane) * 4))
> +#define CSI2RX_STATIC_CFG_LANES_MASK GENMASK(11, 8)
> +
> +#define CSI2RX_STREAM_BASE(n)(((n) + 1) * 0x100)
> +
> +#define CSI2RX_STREAM_CTRL_REG(n)(CSI2RX_STREAM_BASE(n) + 0x000)
> +#define CSI2RX_STREAM_CTRL_START BIT(0)
> +
> +#define CSI2RX_STREAM_DATA_CFG_REG(n)(CSI2RX_STREAM_BASE(n) 
> + 0x008)
> +#define CSI2RX_STREAM_DATA_CFG_EN_VC_SELECT  BIT(31)
> +#define CSI2RX_STREAM_DATA_CFG_VC_SELECT(n)  BIT((n) + 16)
> +
> +#define CSI2RX_STREAM_CFG_REG(n) (CSI2RX_STREAM_BASE(n) + 0x00c)
> +#define CSI2RX_STREAM_CFG_FIFO_MODE_LARGE_BUF(1 << 8)
> +
> +#define CSI2RX_STREAMS_MAX   4
> +
> +enum csi2rx_pads {
> + CSI2RX_PAD_SINK,
> + CSI2RX_PAD_SOURCE_STREAM0,
> + CSI2RX_PAD_SOURCE_STREAM1,
> + CSI2RX_PAD_SOURCE_STREAM2,
> + CSI2RX_PAD_SOURCE_STREAM3,
> + CSI2RX_PAD_MAX,
> +};
> +
> +struct csi2rx_priv {
> + struct device   *dev;
> + atomic_tcount;
> +
> + void __iomem*base;
> + struct clk  *sys_clk;
> + struct clk  *p_clk;
> + struct clk  *pixel_clk[CSI2RX_STREAMS_MAX];
> + struct phy  *dphy;
> +
> + u8  lanes[4];
> + u8  num_lanes;
> + u8  max_lanes;
> + u8  max_streams;
> + boolhas_internal_dphy;
> +
> + struct v4l2_subdev  subdev;
> + struct media_padpads[CSI2RX_PAD_MAX];
> +
> + /* Remote source */
> + struct v4l2_async_subdevasd;
> + struct device_node  *source_node;
> + struct v4l2_subdev  *source_subdev;
> + int source_pad;
> +};
> +
> +static inline
> +struct csi2rx_priv *v4l2_subdev_to_csi2rx(struct v4l2_subdev *subdev)
> +{
> + return container_of(subdev, struct csi2rx_priv, subdev);
> +}
> +
> +static void csi2rx_reset(struct csi2rx_priv *csi2rx)
> +{
> + writel(CSI2RX_SOFT_RESET_PROTOCOL | CSI2RX_SOFT_RESET_FRONT,
> +csi2rx->base + CSI2RX_SOFT_RESET_REG);
> +
> + usleep_range(10, 20);
> +
> + writel(0, csi2rx->base + CSI2RX_SOFT_RESET_REG);
> +}
> +
> +static int csi2rx_start(struct csi2rx_priv *csi2rx)
> +{
> + unsigned int i;
> + u32 reg;
> + int ret;
> +
> + /*
> +  * We're not the first users, there's no need to enable the
> +  * who

Re: IR driver support for tango platforms

2017-09-12 Thread Sean Young
On Tue, Sep 12, 2017 at 05:56:11PM +0200, Mason wrote:
> On 11/09/2017 23:12, Sean Young wrote:
> 
> > On Sep 11, 2017 at 04:37, Mason wrote:
> > 
> > > I'm confused. Does this mean a keymap is mandatory?
> > > I thought it was possible to handle the "scancode to keycode"
> > > step in user-space?
> > 
> > The handling could be better here, but for nec repeats, yes a matching
> > keycode is required here.
> > 
> > 
> > > B) Currently, the driver doesn't seem to allow selective protocol
> > > enabling/disabling. It just silently enables all protocols at init.
> > > 
> > > It would seem useful to add support for that, so that the HW
> > > doesn't fire spurious RC5 interrupts for NEC events.
> > > 
> > > What do you think?
> > 
> > That could be useful. In order to that, have to implement the
> > rc_dev->change_protocol function; in that function, you have to tell
> > the hardware to not generate interrupts for protocols which aren't
> > disabled. So, in order to implement that you'll need to know how
> > to do that. Is there a datasheet available?
> 
> I have access to some documentation, but I was told I cannot share
> it publically :-(
> 
> I've made some progress. I'd like to run the code by you (and Mans,
> the original author), to make sure it is in an acceptable state.
> I tested the driver using ir-keytable and a NEC remote control.
> (RC-5 and RC-6 are untested, for now.)

It looks great, thanks! I have made some minor points below.
 
> # ir-keytable -p nec
> Protocols changed to nec
> 
> # ir-keytable -c
> Old keytable cleared
> 
> # ir-keytable -w sigma.rc
> Wrote 35 keycode(s) to driver
> 
> # ir-keytable -r
> scancode 0x4cb01 = KEY_RIGHT (0x6a)
> scancode 0x4cb02 = KEY_OK (0x160)
> scancode 0x4cb03 = KEY_2 (0x03)
> scancode 0x4cb06 = KEY_UP (0x67)
> scancode 0x4cb07 = KEY_5 (0x06)
> scancode 0x4cb0a = KEY_DOWN (0x6c)
> scancode 0x4cb0f = KEY_SETUP (0x8d)
> scancode 0x4cb16 = KEY_ANGLE (0x173)
> scancode 0x4cb17 = KEY_8 (0x09)
> scancode 0x4cb19 = KEY_ZOOM (0x174)
> scancode 0x4cb1a = KEY_AUDIO (0x188)
> scancode 0x4cb1b = KEY_0 (0x0b)
> scancode 0x4cb1d = KEY_BLUE (0x191)
> scancode 0x4cb1e = KEY_GREEN (0x18f)
> scancode 0x4cb41 = KEY_1 (0x02)
> scancode 0x4cb42 = KEY_3 (0x04)
> scancode 0x4cb43 = KEY_LEFT (0x69)
> scancode 0x4cb44 = KEY_EJECTCD (0xa1)
> scancode 0x4cb45 = KEY_4 (0x05)
> scancode 0x4cb46 = KEY_6 (0x07)
> scancode 0x4cb47 = KEY_BACK (0x9e)
> scancode 0x4cb4a = KEY_POWER (0x74)
> scancode 0x4cb4b = KEY_INFO (0x166)
> scancode 0x4cb4c = KEY_STOP (0x80)
> scancode 0x4cb4f = KEY_TITLE (0x171)
> scancode 0x4cb50 = KEY_PLAY (0xcf)
> scancode 0x4cb51 = KEY_MUTE (0x71)
> scancode 0x4cb53 = KEY_MENU (0x8b)
> scancode 0x4cb54 = KEY_PAUSE (0x77)
> scancode 0x4cb55 = KEY_7 (0x08)
> scancode 0x4cb56 = KEY_9 (0x0a)
> scancode 0x4cb58 = KEY_SUBTITLE (0x172)
> scancode 0x4cb59 = KEY_DELETE (0x6f)
> scancode 0x4cb5c = KEY_YELLOW (0x190)
> scancode 0x4cb5f = KEY_RED (0x18e)
> Enabled protocols: nec
> 
> # ir-keytable -t -v
> Found device /sys/class/rc/rc0/
> Input sysfs node is /sys/class/rc/rc0/input0/
> Event sysfs node is /sys/class/rc/rc0/input0/event0/
> Parsing uevent /sys/class/rc/rc0/input0/event0/uevent
> /sys/class/rc/rc0/input0/event0/uevent uevent MAJOR=13
> /sys/class/rc/rc0/input0/event0/uevent uevent MINOR=64
> /sys/class/rc/rc0/input0/event0/uevent uevent DEVNAME=input/event0
> Parsing uevent /sys/class/rc/rc0/uevent
> /sys/class/rc/rc0/uevent uevent NAME=rc-empty
> /sys/class/rc/rc0/uevent uevent DRV_NAME=tango-ir
> input device is /dev/input/event0
> /sys/class/rc/rc0/protocols protocol rc-5 (disabled)
> /sys/class/rc/rc0/protocols protocol nec (enabled)
> /sys/class/rc/rc0/protocols protocol rc-6 (disabled)
> Opening /dev/input/event0
> Input Protocol version: 0x00010001
> Testing events. Please, press CTRL-C to abort.
> 122.327942: event type EV_MSC(0x04): scancode = 0x4cb41
> 122.327942: event type EV_KEY(0x01) key_down: KEY_1(0x0002)
> 122.327942: event type EV_SYN(0x00).
> 122.381794: event type EV_MSC(0x04): scancode = 0x4cb41
> 122.381794: event type EV_SYN(0x00).
> 122.489565: event type EV_MSC(0x04): scancode = 0x4cb41
> 122.489565: event type EV_SYN(0x00).
> 122.597335: event type EV_MSC(0x04): scancode = 0x4cb41
> 122.597335: event type EV_SYN(0x00).
> 122.705110: event type EV_MSC(0x04): scancode = 0x4cb41
> 122.705110: event type EV_SYN(0x00).
> 122.812883: event type EV_MSC(0x04): scancode = 0x4cb41
> 122.812883: event type EV_SYN(0x00).
> 122.853335: event type EV_KEY(0x01) key_down: KEY_1(0x0002)
> 122.853335: event type EV_SYN(0x00).
> 122.920659: event type EV_MSC(0x04): scancode = 0x4cb41
> 122.920659: event type EV_SYN(0x00).
> 122.983335: event type EV_KEY(0x01) key_down: KEY_1(0x0002)
> 122.983335: event type EV_SYN(0x00).
> 123.028428: event type EV_MSC(0x04): scancode = 0x4cb41
> 123.028428: event type EV_SYN(0x00).
> 123.113334: event type EV_KEY(0x01) key_down: KEY_1(0x0002)
> 123.113334: event type EV_SYN(0x00).
> 123.24: event type EV_KEY(0x01) key_

Re: [media] s5p-mfc: Adjust a null pointer check in four functions

2017-09-12 Thread Sylwester Nawrocki

On 09/12/2017 05:00 PM, SF Markus Elfring wrote:

* Do you care to preserve an information like the author date?

In this case not, but actually the Date line is not an issue.

Thanks for your information.

It seems then that you quoted a line too much.
 

Anyway the patch is malformed, …

>

I have got doubts for this view because the file was automatically generated
by the command “git format-patch” also for the discussed three update steps.


Generating patch is only part of the story, it seems the patch is not sent
properly and tags which should be in SMTP header end up in the message
body. I think there would not be such issues if you have used git format-patch
+ git send-email.

I normally do amend things like this while applying, I will do that this time 
as well. It's already too much time wasted for such a dubious patch.


--
Thanks,
Sylwester


Re: [PATCHv3 1/3] drm: add support for DisplayPort CEC-Tunneling-over-AUX

2017-09-12 Thread Ville Syrjälä
On Mon, Sep 11, 2017 at 01:25:45PM +0200, Hans Verkuil wrote:
> From: Hans Verkuil 
> 
> This adds support for the DisplayPort CEC-Tunneling-over-AUX
> feature that is part of the DisplayPort 1.3 standard.
> 
> Unfortunately, not all DisplayPort/USB-C to HDMI adapters with a
> chip that has this capability actually hook up the CEC pin, so
> even though a CEC device is created, it may not actually work.
> 
> Signed-off-by: Hans Verkuil 
> Tested-by: Carlos Santa 
> ---
>  drivers/gpu/drm/Kconfig  |  10 ++
>  drivers/gpu/drm/Makefile |   1 +
>  drivers/gpu/drm/drm_dp_cec.c | 301 
> +++
>  include/drm/drm_dp_helper.h  |  24 
>  4 files changed, 336 insertions(+)
>  create mode 100644 drivers/gpu/drm/drm_dp_cec.c
> 
> diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig
> index 83cb2a88c204..1f2708df5c4e 100644
> --- a/drivers/gpu/drm/Kconfig
> +++ b/drivers/gpu/drm/Kconfig
> @@ -120,6 +120,16 @@ config DRM_LOAD_EDID_FIRMWARE
> default case is N. Details and instructions how to build your own
> EDID data are given in Documentation/EDID/HOWTO.txt.
>  
> +config DRM_DP_CEC
> + bool "Enable DisplayPort CEC-Tunneling-over-AUX HDMI support"
> + select CEC_CORE
> + help
> +   Choose this option if you want to enable HDMI CEC support for
> +   DisplayPort/USB-C to HDMI adapters.
> +
> +   Note: not all adapters support this feature, and even for those
> +   that do support this they often do not hook up the CEC pin.
> +
>  config DRM_TTM
>   tristate
>   depends on DRM && MMU
> diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile
> index 24a066e1841c..c6552c62049e 100644
> --- a/drivers/gpu/drm/Makefile
> +++ b/drivers/gpu/drm/Makefile
> @@ -40,6 +40,7 @@ drm_kms_helper-$(CONFIG_DRM_LOAD_EDID_FIRMWARE) += 
> drm_edid_load.o
>  drm_kms_helper-$(CONFIG_DRM_FBDEV_EMULATION) += drm_fb_helper.o
>  drm_kms_helper-$(CONFIG_DRM_KMS_CMA_HELPER) += drm_fb_cma_helper.o
>  drm_kms_helper-$(CONFIG_DRM_DP_AUX_CHARDEV) += drm_dp_aux_dev.o
> +drm_kms_helper-$(CONFIG_DRM_DP_CEC) += drm_dp_cec.o
>  
>  obj-$(CONFIG_DRM_KMS_HELPER) += drm_kms_helper.o
>  obj-$(CONFIG_DRM_DEBUG_MM_SELFTEST) += selftests/
> diff --git a/drivers/gpu/drm/drm_dp_cec.c b/drivers/gpu/drm/drm_dp_cec.c
> new file mode 100644
> index ..b831bb72c932
> --- /dev/null
> +++ b/drivers/gpu/drm/drm_dp_cec.c
> @@ -0,0 +1,301 @@
> +/*
> + * DisplayPort CEC-Tunneling-over-AUX support
> + *
> + * Copyright 2017 Cisco Systems, Inc. and/or its affiliates. All rights 
> reserved.
> + *
> + * This program is free software; you may redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation; version 2 of the License.
> + *
> + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
> + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
> + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
> + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
> + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
> + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
> + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
> + * SOFTWARE.
> + */
> +
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +
> +/*
> + * Unfortunately it turns out that we have a chicken-and-egg situation
> + * here. Quite a few active (mini-)DP-to-HDMI or USB-C-to-HDMI adapters
> + * have a converter chip that supports CEC-Tunneling-over-AUX (usually the
> + * Parade PS176), but they do not wire up the CEC pin, thus making CEC
> + * useless.
> + *
> + * Sadly there is no way for this driver to know this. What happens is
> + * that a /dev/cecX device is created that is isolated and unable to see
> + * any of the other CEC devices. Quite literally the CEC wire is cut
> + * (or in this case, never connected in the first place).
> + *
> + * I suspect that the reason so few adapters support this is that this
> + * tunneling protocol was never supported by any OS. So there was no
> + * easy way of testing it, and no incentive to correctly wire up the
> + * CEC pin.
> + *
> + * Hopefully by creating this driver it will be easier for vendors to
> + * finally fix their adapters and test the CEC functionality.
> + *
> + * I keep a list of known working adapters here:
> + *
> + * https://hverkuil.home.xs4all.nl/cec-status.txt
> + *
> + * Please mail me (hverk...@xs4all.nl) if you find an adapter that works
> + * and is not yet listed there.
> + */
> +
> +/**
> + * DOC: dp cec helpers
> + *
> + * These functions take care of supporting the CEC-Tunneling-over-AUX
> + * feature of DisplayPort-to-HDMI adapters.
> + */
> +
> +static int drm_dp_cec_adap_enable(struct cec_adapter *adap, bool enable)
> +{
> + struct drm_dp_aux *aux = cec_get_drvdata(adap);
> + u32 val = enable ? DP_CEC_TUNNELING_ENAB

Kindly please view the attach document and get back to me

2017-09-12 Thread Mr. David


---
This email has been checked for viruses by Avast antivirus software.
https://www.avast.com/antivirus


Desk of Mr.pdf
Description: Adobe PDF document


Re: [PATCH v4 1/2] media:imx274 device tree binding file

2017-09-12 Thread Rob Herring
On Fri, Sep 01, 2017 at 01:32:42PM -0700, Leon Luo wrote:
> The binding file for imx274 CMOS sensor V4l2 driver
> 
> Signed-off-by: Leon Luo 
> ---
> v4:
>  - no changes
> v3:
>  - remove redundant properties and references
>  - document 'reg' property
> v2:
>  - no changes
> ---
>  .../devicetree/bindings/media/i2c/imx274.txt   | 32 
> ++
>  1 file changed, 32 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/media/i2c/imx274.txt
> 
> diff --git a/Documentation/devicetree/bindings/media/i2c/imx274.txt 
> b/Documentation/devicetree/bindings/media/i2c/imx274.txt
> new file mode 100644
> index ..1f03256b35db
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/media/i2c/imx274.txt
> @@ -0,0 +1,32 @@
> +* Sony 1/2.5-Inch 8.51Mp CMOS Digital Image Sensor
> +
> +The Sony imx274 is a 1/2.5-inch CMOS active pixel digital image sensor with
> +an active array size of 3864H x 2202V. It is programmable through I2C
> +interface. The I2C address is fixed to 0x1a as per sensor data sheet.
> +Image data is sent through MIPI CSI-2, which is configured as 4 lanes
> +at 1440 Mbps.
> +
> +
> +Required Properties:
> +- compatible: value should be "sony,imx274" for imx274 sensor
> +- reg: I2C bus address of the device
> +
> +Optional Properties:
> +- reset-gpios: Sensor reset GPIO
> +
> +For further reading on port node refer to
> +Documentation/devicetree/bindings/media/video-interfaces.txt.

You need to specify here exactly how many ports and endpoints for each 
port. With that,

Acked-by: Rob Herring 


Re: IR driver support for tango platforms

2017-09-12 Thread Mason

On 11/09/2017 23:12, Sean Young wrote:


On Sep 11, 2017 at 04:37, Mason wrote:


I'm confused. Does this mean a keymap is mandatory?
I thought it was possible to handle the "scancode to keycode"
step in user-space?


The handling could be better here, but for nec repeats, yes a matching
keycode is required here.



B) Currently, the driver doesn't seem to allow selective protocol
enabling/disabling. It just silently enables all protocols at init.

It would seem useful to add support for that, so that the HW
doesn't fire spurious RC5 interrupts for NEC events.

What do you think?


That could be useful. In order to that, have to implement the
rc_dev->change_protocol function; in that function, you have to tell
the hardware to not generate interrupts for protocols which aren't
disabled. So, in order to implement that you'll need to know how
to do that. Is there a datasheet available?


I have access to some documentation, but I was told I cannot share
it publically :-(

I've made some progress. I'd like to run the code by you (and Mans,
the original author), to make sure it is in an acceptable state.
I tested the driver using ir-keytable and a NEC remote control.
(RC-5 and RC-6 are untested, for now.)

# ir-keytable -p nec
Protocols changed to nec

# ir-keytable -c
Old keytable cleared

# ir-keytable -w sigma.rc
Wrote 35 keycode(s) to driver

# ir-keytable -r
scancode 0x4cb01 = KEY_RIGHT (0x6a)
scancode 0x4cb02 = KEY_OK (0x160)
scancode 0x4cb03 = KEY_2 (0x03)
scancode 0x4cb06 = KEY_UP (0x67)
scancode 0x4cb07 = KEY_5 (0x06)
scancode 0x4cb0a = KEY_DOWN (0x6c)
scancode 0x4cb0f = KEY_SETUP (0x8d)
scancode 0x4cb16 = KEY_ANGLE (0x173)
scancode 0x4cb17 = KEY_8 (0x09)
scancode 0x4cb19 = KEY_ZOOM (0x174)
scancode 0x4cb1a = KEY_AUDIO (0x188)
scancode 0x4cb1b = KEY_0 (0x0b)
scancode 0x4cb1d = KEY_BLUE (0x191)
scancode 0x4cb1e = KEY_GREEN (0x18f)
scancode 0x4cb41 = KEY_1 (0x02)
scancode 0x4cb42 = KEY_3 (0x04)
scancode 0x4cb43 = KEY_LEFT (0x69)
scancode 0x4cb44 = KEY_EJECTCD (0xa1)
scancode 0x4cb45 = KEY_4 (0x05)
scancode 0x4cb46 = KEY_6 (0x07)
scancode 0x4cb47 = KEY_BACK (0x9e)
scancode 0x4cb4a = KEY_POWER (0x74)
scancode 0x4cb4b = KEY_INFO (0x166)
scancode 0x4cb4c = KEY_STOP (0x80)
scancode 0x4cb4f = KEY_TITLE (0x171)
scancode 0x4cb50 = KEY_PLAY (0xcf)
scancode 0x4cb51 = KEY_MUTE (0x71)
scancode 0x4cb53 = KEY_MENU (0x8b)
scancode 0x4cb54 = KEY_PAUSE (0x77)
scancode 0x4cb55 = KEY_7 (0x08)
scancode 0x4cb56 = KEY_9 (0x0a)
scancode 0x4cb58 = KEY_SUBTITLE (0x172)
scancode 0x4cb59 = KEY_DELETE (0x6f)
scancode 0x4cb5c = KEY_YELLOW (0x190)
scancode 0x4cb5f = KEY_RED (0x18e)
Enabled protocols: nec

# ir-keytable -t -v
Found device /sys/class/rc/rc0/
Input sysfs node is /sys/class/rc/rc0/input0/
Event sysfs node is /sys/class/rc/rc0/input0/event0/
Parsing uevent /sys/class/rc/rc0/input0/event0/uevent
/sys/class/rc/rc0/input0/event0/uevent uevent MAJOR=13
/sys/class/rc/rc0/input0/event0/uevent uevent MINOR=64
/sys/class/rc/rc0/input0/event0/uevent uevent DEVNAME=input/event0
Parsing uevent /sys/class/rc/rc0/uevent
/sys/class/rc/rc0/uevent uevent NAME=rc-empty
/sys/class/rc/rc0/uevent uevent DRV_NAME=tango-ir
input device is /dev/input/event0
/sys/class/rc/rc0/protocols protocol rc-5 (disabled)
/sys/class/rc/rc0/protocols protocol nec (enabled)
/sys/class/rc/rc0/protocols protocol rc-6 (disabled)
Opening /dev/input/event0
Input Protocol version: 0x00010001
Testing events. Please, press CTRL-C to abort.
122.327942: event type EV_MSC(0x04): scancode = 0x4cb41
122.327942: event type EV_KEY(0x01) key_down: KEY_1(0x0002)
122.327942: event type EV_SYN(0x00).
122.381794: event type EV_MSC(0x04): scancode = 0x4cb41
122.381794: event type EV_SYN(0x00).
122.489565: event type EV_MSC(0x04): scancode = 0x4cb41
122.489565: event type EV_SYN(0x00).
122.597335: event type EV_MSC(0x04): scancode = 0x4cb41
122.597335: event type EV_SYN(0x00).
122.705110: event type EV_MSC(0x04): scancode = 0x4cb41
122.705110: event type EV_SYN(0x00).
122.812883: event type EV_MSC(0x04): scancode = 0x4cb41
122.812883: event type EV_SYN(0x00).
122.853335: event type EV_KEY(0x01) key_down: KEY_1(0x0002)
122.853335: event type EV_SYN(0x00).
122.920659: event type EV_MSC(0x04): scancode = 0x4cb41
122.920659: event type EV_SYN(0x00).
122.983335: event type EV_KEY(0x01) key_down: KEY_1(0x0002)
122.983335: event type EV_SYN(0x00).
123.028428: event type EV_MSC(0x04): scancode = 0x4cb41
123.028428: event type EV_SYN(0x00).
123.113334: event type EV_KEY(0x01) key_down: KEY_1(0x0002)
123.113334: event type EV_SYN(0x00).
123.24: event type EV_KEY(0x01) key_down: KEY_1(0x0002)
123.24: event type EV_SYN(0x00).
123.28: event type EV_KEY(0x01) key_up: KEY_1(0x0002)
123.28: event type EV_SYN(0x00).
134.743698: event type EV_MSC(0x04): scancode = 0x4cb50
134.743698: event type EV_KEY(0x01) key_down: KEY_PLAY(0x00cf)
134.743698: event type EV_SYN(0x00).
134.797577: event type EV_MSC(0x04): scancode = 0x4cb50
134.797577: event type EV_SYN(0x00).
134.905349: event ty

Re: Duplicated debug message in drivers/media/rc/rc-main.c

2017-09-12 Thread Sean Young
Hi Mason,

On Tue, Sep 12, 2017 at 02:39:14PM +0200, Mason wrote:
> Hello,
> 
> I enabled all debug messages, and I see:
> 
> [1.931214] Allocated space for 1 keycode entries (8 bytes)
> [1.936822] Allocated space for 1 keycode entries (8 bytes)
> 
> One comes from ir_create_table()
> The other from ir_setkeytable()
> 
> ir_setkeytable() calls ir_create_table()
> 
> It looks like one of the two debug messages should be deleted?

Yes, you're right. Patches are welcome :)

Thanks

Sean


Re: [media] s5p-mfc: Adjust a null pointer check in four functions

2017-09-12 Thread SF Markus Elfring

>> * Do you care to preserve an information like the author date?
>
> In this case not, but actually the Date line is not an issue.

Thanks for your information.

It seems then that you quoted a line too much.


> Anyway the patch is malformed, …

I have got doubts for this view because the file was automatically generated
by the command “git format-patch” also for the discussed three update steps.

Regards,
Markus


Re: [PATCHv4 3/5] dt-bindings: document the CEC GPIO bindings

2017-09-12 Thread Rob Herring
On Thu, Aug 31, 2017 at 01:01:54PM +0200, Hans Verkuil wrote:
> From: Hans Verkuil 
> 
> Document the bindings for the cec-gpio module for hardware where the
> CEC line and optionally the HPD line are connected to GPIO lines.
> 
> Signed-off-by: Hans Verkuil 
> ---
>  .../devicetree/bindings/media/cec-gpio.txt | 22 
> ++
>  1 file changed, 22 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/media/cec-gpio.txt
> 
> diff --git a/Documentation/devicetree/bindings/media/cec-gpio.txt 
> b/Documentation/devicetree/bindings/media/cec-gpio.txt
> new file mode 100644
> index ..db20a7452dbd
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/media/cec-gpio.txt
> @@ -0,0 +1,22 @@
> +* HDMI CEC GPIO driver
> +
> +The HDMI CEC GPIO module supports CEC implementations where the CEC line
> +is hooked up to a pull-up GPIO line and - optionally - the HPD line is
> +hooked up to another GPIO line.
> +
> +Required properties:
> +  - compatible: value must be "cec-gpio"
> +  - cec-gpio: gpio that the CEC line is connected to

cec-gpios

> +
> +Optional property:
> +  - hpd-gpio: gpio that the HPD line is connected to

hpd-gpios

However, HPD is already part of the HDMI connector binding. Having it in 
2 places would be wrong.

I think we should have either:

hdmi-connector {
compatible = 'hdmi-connector-a";
hpd-gpios = <...>;
cec-gpios = <...>;
ports {
// port to HDMI controller
...
};
};

Or:

hdmi-connector {
compatible = 'hdmi-connector-a";
hpd-gpios = <...>;
cec = <&cec>;
... 
};

cec: cec-gpio {
compatible = "cec-gpio";
cec-gpios = <...>;
};

My preference is probably the former. The latter just helps create a 
device to bind to a driver, but DT is not the only way to create 
devices. Then again, if you have a phandle to real CEC controllers in 
the HDMI connector node, it may make sense to do the same thing with 
cec-gpio. 

> +
> +Example for the Raspberry Pi 3 where the CEC line is connected to
> +pin 26 aka BCM7 aka CE1 on the GPIO pin header and the HPD line is
> +connected to pin 11 aka BCM17:
> +
> +cec-gpio@7 {

unit address is not valid. Build your dts's with W=2.

> +   compatible = "cec-gpio";
> +   cec-gpio = <&gpio 7 GPIO_OPEN_DRAIN>;
> +   hpd-gpio = <&gpio 17 GPIO_ACTIVE_HIGH>;
> +};
> -- 
> 2.14.1
> 
> --
> To unsubscribe from this list: send the line "unsubscribe devicetree" in
> the body of a message to majord...@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [Outreachy kernel] [PATCH] Staging: media: atomisp: Merge assignment with return

2017-09-12 Thread Julia Lawall


On Tue, 12 Sep 2017, Srishti Sharma wrote:

> Merge the assignment and the return statements to return the value
> directly. Done using the following semantic patch by coccinelle.
>
> @@
> local idexpression ret;
> expression e;
> @@
>
> -ret =
> +return
>  e;
> -return ret;
>
> Signed-off-by: Srishti Sharma 

Acked-by: Julia Lawall 


> ---
>  drivers/staging/media/atomisp/pci/atomisp2/hmm/hmm_bo.c | 6 +-
>  1 file changed, 1 insertion(+), 5 deletions(-)
>
> diff --git a/drivers/staging/media/atomisp/pci/atomisp2/hmm/hmm_bo.c 
> b/drivers/staging/media/atomisp/pci/atomisp2/hmm/hmm_bo.c
> index 11162f5..e6ddfbf 100644
> --- a/drivers/staging/media/atomisp/pci/atomisp2/hmm/hmm_bo.c
> +++ b/drivers/staging/media/atomisp/pci/atomisp2/hmm/hmm_bo.c
> @@ -1168,13 +1168,9 @@ void hmm_bo_free_pages(struct hmm_buffer_object *bo)
>
>  int hmm_bo_page_allocated(struct hmm_buffer_object *bo)
>  {
> - int ret;
> -
>   check_bo_null_return(bo, 0);
>
> - ret = bo->status & HMM_BO_PAGE_ALLOCED;
> -
> - return ret;
> + return bo->status & HMM_BO_PAGE_ALLOCED;
>  }
>
>  /*
> --
> 2.7.4
>
> --
> You received this message because you are subscribed to the Google Groups 
> "outreachy-kernel" group.
> To unsubscribe from this group and stop receiving emails from it, send an 
> email to outreachy-kernel+unsubscr...@googlegroups.com.
> To post to this group, send email to outreachy-ker...@googlegroups.com.
> To view this discussion on the web visit 
> https://groups.google.com/d/msgid/outreachy-kernel/1505226307-5119-1-git-send-email-srishtishar%40gmail.com.
> For more options, visit https://groups.google.com/d/optout.
>


[PATCH] Staging: media: atomisp: Merge assignment with return

2017-09-12 Thread Srishti Sharma
Merge the assignment and the return statements to return the value
directly. Done using the following semantic patch by coccinelle.

@@
local idexpression ret;
expression e;
@@

-ret =
+return
 e;
-return ret;

Signed-off-by: Srishti Sharma 
---
 drivers/staging/media/atomisp/pci/atomisp2/hmm/hmm_bo.c | 6 +-
 1 file changed, 1 insertion(+), 5 deletions(-)

diff --git a/drivers/staging/media/atomisp/pci/atomisp2/hmm/hmm_bo.c 
b/drivers/staging/media/atomisp/pci/atomisp2/hmm/hmm_bo.c
index 11162f5..e6ddfbf 100644
--- a/drivers/staging/media/atomisp/pci/atomisp2/hmm/hmm_bo.c
+++ b/drivers/staging/media/atomisp/pci/atomisp2/hmm/hmm_bo.c
@@ -1168,13 +1168,9 @@ void hmm_bo_free_pages(struct hmm_buffer_object *bo)
 
 int hmm_bo_page_allocated(struct hmm_buffer_object *bo)
 {
-   int ret;
-
check_bo_null_return(bo, 0);
 
-   ret = bo->status & HMM_BO_PAGE_ALLOCED;
-
-   return ret;
+   return bo->status & HMM_BO_PAGE_ALLOCED;
 }
 
 /*
-- 
2.7.4



Re: [Outreachy kernel] [PATCH] Staging: media: atomisp: Merge assignment with return

2017-09-12 Thread Julia Lawall


On Tue, 12 Sep 2017, Srishti Sharma wrote:

> Merge the assignment and the return statements to return the value
> directly. Done using the following semantic patch by coccinelle.
>
> @@
> local idexpression ret;
> expression e;
> @@
>
> -ret =
> +return
>  e;
> -return ret;
>
> Signed-off-by: Srishti Sharma 

Acked-by: Julia Lawall 

> ---
>  drivers/staging/media/atomisp/i2c/ov5693/ov5693.c | 11 ++-
>  1 file changed, 2 insertions(+), 9 deletions(-)
>
> diff --git a/drivers/staging/media/atomisp/i2c/ov5693/ov5693.c 
> b/drivers/staging/media/atomisp/i2c/ov5693/ov5693.c
> index 1236425..2195011 100644
> --- a/drivers/staging/media/atomisp/i2c/ov5693/ov5693.c
> +++ b/drivers/staging/media/atomisp/i2c/ov5693/ov5693.c
> @@ -945,12 +945,8 @@ static int ad5823_t_focus_vcm(struct v4l2_subdev *sd, 
> u16 val)
>
>  int ad5823_t_focus_abs(struct v4l2_subdev *sd, s32 value)
>  {
> - int ret;
> -
>   value = min(value, AD5823_MAX_FOCUS_POS);
> - ret = ad5823_t_focus_vcm(sd, value);
> -
> - return ret;
> + return ad5823_t_focus_vcm(sd, value);
>  }
>
>  static int ov5693_t_focus_abs(struct v4l2_subdev *sd, s32 value)
> @@ -1332,7 +1328,6 @@ static int power_ctrl(struct v4l2_subdev *sd, bool flag)
>
>  static int gpio_ctrl(struct v4l2_subdev *sd, bool flag)
>  {
> - int ret;
>   struct ov5693_device *dev = to_ov5693_sensor(sd);
>
>   if (!dev || !dev->platform_data)
> @@ -1342,9 +1337,7 @@ static int gpio_ctrl(struct v4l2_subdev *sd, bool flag)
>   if (dev->platform_data->gpio_ctrl)
>   return dev->platform_data->gpio_ctrl(sd, flag);
>
> - ret = dev->platform_data->gpio0_ctrl(sd, flag);
> -
> - return ret;
> + return dev->platform_data->gpio0_ctrl(sd, flag);
>  }
>
>  static int __power_up(struct v4l2_subdev *sd)
> --
> 2.7.4
>
> --
> You received this message because you are subscribed to the Google Groups 
> "outreachy-kernel" group.
> To unsubscribe from this group and stop receiving emails from it, send an 
> email to outreachy-kernel+unsubscr...@googlegroups.com.
> To post to this group, send email to outreachy-ker...@googlegroups.com.
> To view this discussion on the web visit 
> https://groups.google.com/d/msgid/outreachy-kernel/1505225549-4432-1-git-send-email-srishtishar%40gmail.com.
> For more options, visit https://groups.google.com/d/optout.
>


[PATCH] Staging: media: atomisp: Merge assignment with return

2017-09-12 Thread Srishti Sharma
Merge the assignment and the return statements to return the value
directly. Done using the following semantic patch by coccinelle.

@@
local idexpression ret;
expression e;
@@

-ret =
+return
 e;
-return ret;

Signed-off-by: Srishti Sharma 
---
 drivers/staging/media/atomisp/i2c/ov5693/ov5693.c | 11 ++-
 1 file changed, 2 insertions(+), 9 deletions(-)

diff --git a/drivers/staging/media/atomisp/i2c/ov5693/ov5693.c 
b/drivers/staging/media/atomisp/i2c/ov5693/ov5693.c
index 1236425..2195011 100644
--- a/drivers/staging/media/atomisp/i2c/ov5693/ov5693.c
+++ b/drivers/staging/media/atomisp/i2c/ov5693/ov5693.c
@@ -945,12 +945,8 @@ static int ad5823_t_focus_vcm(struct v4l2_subdev *sd, u16 
val)
 
 int ad5823_t_focus_abs(struct v4l2_subdev *sd, s32 value)
 {
-   int ret;
-
value = min(value, AD5823_MAX_FOCUS_POS);
-   ret = ad5823_t_focus_vcm(sd, value);
-
-   return ret;
+   return ad5823_t_focus_vcm(sd, value);
 }
 
 static int ov5693_t_focus_abs(struct v4l2_subdev *sd, s32 value)
@@ -1332,7 +1328,6 @@ static int power_ctrl(struct v4l2_subdev *sd, bool flag)
 
 static int gpio_ctrl(struct v4l2_subdev *sd, bool flag)
 {
-   int ret;
struct ov5693_device *dev = to_ov5693_sensor(sd);
 
if (!dev || !dev->platform_data)
@@ -1342,9 +1337,7 @@ static int gpio_ctrl(struct v4l2_subdev *sd, bool flag)
if (dev->platform_data->gpio_ctrl)
return dev->platform_data->gpio_ctrl(sd, flag);
 
-   ret = dev->platform_data->gpio0_ctrl(sd, flag);
-
-   return ret;
+   return dev->platform_data->gpio0_ctrl(sd, flag);
 }
 
 static int __power_up(struct v4l2_subdev *sd)
-- 
2.7.4



[PATCH v12 14/26] v4l: async: Allow async notifier register call succeed with no subdevs

2017-09-12 Thread Sakari Ailus
The information on how many async sub-devices would be bindable to a
notifier is typically dependent on information from platform firmware and
it's not driver's business to be aware of that.

Many V4L2 main drivers are perfectly usable (and useful) without async
sub-devices and so if there aren't any around, just proceed call the
notifier's complete callback immediately without registering the notifier
itself.

If a driver needs to check whether there are async sub-devices available,
it can be done by inspecting the notifier's num_subdevs field which tells
the number of async sub-devices.

Signed-off-by: Sakari Ailus 
Acked-by: Hans Verkuil 
---
 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 7b396ff4302b..4525b03d59c1 100644
--- a/drivers/media/v4l2-core/v4l2-async.c
+++ b/drivers/media/v4l2-core/v4l2-async.c
@@ -170,14 +170,16 @@ int v4l2_async_notifier_register(struct v4l2_device 
*v4l2_dev,
struct v4l2_async_subdev *asd;
int i;
 
-   if (!v4l2_dev || !notifier->num_subdevs ||
-   notifier->num_subdevs > V4L2_MAX_SUBDEVS)
+   if (!v4l2_dev || notifier->num_subdevs > V4L2_MAX_SUBDEVS)
return -EINVAL;
 
notifier->v4l2_dev = v4l2_dev;
INIT_LIST_HEAD(¬ifier->waiting);
INIT_LIST_HEAD(¬ifier->done);
 
+   if (!notifier->num_subdevs)
+   return v4l2_async_notifier_call_complete(notifier);
+
for (i = 0; i < notifier->num_subdevs; i++) {
asd = notifier->subdevs[i];
 
-- 
2.11.0



[PATCH v12 00/30] Unified fwnode endpoint parser, async sub-device notifier support, N9 flash DTS

2017-09-12 Thread Sakari Ailus
Hi folks,

We have a large influx of new, unmerged, drivers that are now parsing
fwnode endpoints and each one of them is doing this a little bit
differently. The needs are still exactly the same for the graph data
structure is device independent. This is still a non-trivial task and the
majority of the driver implementations are buggy, just buggy in different
ways.

Facilitate parsing endpoints by adding a convenience function for parsing
the endpoints, and make the omap3isp and rcar-vin drivers use them as an
example.

To show where we're getting with this, I've added support for async
sub-device notifier support that is notifiers that can be registered by
sub-device drivers as well as V4L2 fwnode improvements to make use of them
and the DTS changes for the Nokia N9. Some of these patches I've posted
previously in this set here:

http://www.spinics.net/lists/linux-media/msg118764.html>

Since that, the complete callback of the master notifier registering the
V4L2 device is only called once all sub-notifiers have been completed as
well. This way the device node creation can be postponed until all devices
have been successfully initialised.

With this, the as3645a driver successfully registers a sub-device to the
media device created by the omap3isp driver. The kernel also has the
information it's related to the sensor driven by the smiapp driver but we
don't have a way to expose that information yet.

since v11:

- Add patch "et8ek8: Add support for flash and lens devices".

- Add patch "v4l: fwnode: Support generic parsing of graph endpoints, per
  port". The use case for this is to parse only upstream ports in a device
  with sources and sinks. The downstream ports have already been parsed by
  other drivers.

- Rename v4l2_fwnode_reference_parse_sensor_common as
  v4l2_async_notifier_parse_fwnode_sensor_common. This is in line with
  other functions that parse information using fwnode API and set up async
  sub-devices in the notifier.

since v10:

- Rename v4l2_async_get_subdev_notifier as
  v4l2_async_find_subdev_notifier, as this is what it effectively does:
  finds a notifier for a sub-device. Same for v4l2_async_notifier_get_v4l2_dev
  / v4l2_async_notifier_get_v4l2_dev.

- Initialise lists before calling v4l2_async_notifier_call_complete() if
  there are no sub-devices in a notifier.

- Warn on missing sub-device or existing v4l2_device on sub-device
  notifier register, and conversely missing v4l2_device or existing
  sub-device for a master notifier.

- Set notifier's sd and v4l2_dev fields NULL when the sub-device is
  unregistered.

- Document the newly added helper functions for parsing external
  references in v4l2-fwnode.c better.

- Return -ENOENT in v4l2_fwnode_reference_parse if no entries are found,
  and other errors as they occur.

- Turn the loop in v4l2_fwnode_reference_get_int_prop a while loop (was
  for).

- Don't put fwnodes in v4l2_fwnode_reference_parse_int_props.

- Fix description of parent field in struct v4l2_async_notifier.

- In the documentation of v4l2_async_notifier_release, document that this
  function must be called also after
  v4l2_fwnode_reference_parse_sensor_common, not just
  v4l2_async_notifier_parse_fwnode_endpoints. The same goes for
  v4l2_async_notifier_parse_fwnode_endpoints as well as
  v4l2_fwnode_reference_parse_sensor_common.

since v9:

- Drop "as3645a: Switch to fwnode property API" and "ACPI: Document how to
  refer to LEDs from remote nodes" patches. They're better off separately
  from this set.

- Address property documentation redundancy in smiapp DT binding
  documentation.

- Add patches "ov5670: Add support for flash and lens devices" and
  "ov13858: Add support for flash and lens devices".

since v8:

- Improve terminology for notifiers. Instead of master / subdev, we
  have root, parent and subdev notifiers.

- Renamed "flash" property as "flash-leds". There are many, and currently
  we make assumptions in a lot of places (e.g. LED bindings) that these
  are LEDs. While we don't have any other types of flashes supported right
  now (e.g. Xenon), it's safer to assume we might have them in the future.

- Use ENOTCONN instead of EPERM to tell from driver's callback function
  that an endpoint is to be skipped but not handled as an error.

- Avoid accessing notifier's subdevs array as well as num_subdevs field
  from rcar-vin driver.

- Add a patch "v4l: async: Allow async notifier register call succeed with no
  subdevs", which allows, well, what the subject says.

- Move checks for subdev / v4l2_dev from __v4l2_async_notifier_register()
  to v4l2_async_notifier_register() and
  v4l2_async_subdev_notifier_register().

- Don't initialise notifier->list. There was no need to do so, as this is
  the entry added to the list and not used otherwise. I.e. regarding this,
  the state before this patchset is restored.

- Clean up error handling in v4l2_async_notifier_fwnode_parse_endpoint().

- WARN_ON() in v4l2_async_notifier_parse_fwnode_endpoint

[PATCH v12 16/26] dt: bindings: Add a binding for flash LED devices associated to a sensor

2017-09-12 Thread Sakari Ailus
Camera flash drivers (and LEDs) are separate from the sensor devices in
DT. In order to make an association between the two, provide the
association information to the software.

Signed-off-by: Sakari Ailus 
Acked-by: Rob Herring 
Acked-by: Hans Verkuil 
Acked-by: Pavel Machek 
---
 Documentation/devicetree/bindings/media/video-interfaces.txt | 8 
 1 file changed, 8 insertions(+)

diff --git a/Documentation/devicetree/bindings/media/video-interfaces.txt 
b/Documentation/devicetree/bindings/media/video-interfaces.txt
index 852041a7480c..fdba30479b47 100644
--- a/Documentation/devicetree/bindings/media/video-interfaces.txt
+++ b/Documentation/devicetree/bindings/media/video-interfaces.txt
@@ -67,6 +67,14 @@ are required in a relevant parent node:
identifier, should be 1.
  - #size-cells: should be zero.
 
+
+Optional properties
+---
+
+- flash-leds: An array of phandles, each referring to a flash LED, a sub-node
+  of the LED driver device node.
+
+
 Optional endpoint properties
 
 
-- 
2.11.0



[PATCH v12 15/26] v4l: async: Allow binding notifiers to sub-devices

2017-09-12 Thread Sakari Ailus
Registering a notifier has required the knowledge of struct v4l2_device
for the reason that sub-devices generally are registered to the
v4l2_device (as well as the media device, also available through
v4l2_device).

This information is not available for sub-device drivers at probe time.

What this patch does is that it allows registering notifiers without
having v4l2_device around. Instead the sub-device pointer is stored in the
notifier. Once the sub-device of the driver that registered the notifier
is registered, the notifier will gain the knowledge of the v4l2_device,
and the binding of async sub-devices from the sub-device driver's notifier
may proceed.

The root notifier's complete callback is only called when all sub-device
notifiers are completed.

Signed-off-by: Sakari Ailus 
---
 drivers/media/v4l2-core/v4l2-async.c | 219 ++-
 include/media/v4l2-async.h   |  16 ++-
 2 files changed, 204 insertions(+), 31 deletions(-)

diff --git a/drivers/media/v4l2-core/v4l2-async.c 
b/drivers/media/v4l2-core/v4l2-async.c
index 4525b03d59c1..5082b01d2b96 100644
--- a/drivers/media/v4l2-core/v4l2-async.c
+++ b/drivers/media/v4l2-core/v4l2-async.c
@@ -53,6 +53,10 @@ static int v4l2_async_notifier_call_complete(struct 
v4l2_async_notifier *n)
return n->ops->complete(n);
 }
 
+static int v4l2_async_match_notify(struct v4l2_async_notifier *notifier,
+  struct v4l2_subdev *sd,
+  struct v4l2_async_subdev *asd);
+
 static bool match_i2c(struct v4l2_subdev *sd, struct v4l2_async_subdev *asd)
 {
 #if IS_ENABLED(CONFIG_I2C)
@@ -124,14 +128,128 @@ static struct v4l2_async_subdev *v4l2_async_find_match(
return NULL;
 }
 
+/* Find the sub-device notifier registered by a sub-device driver. */
+static struct v4l2_async_notifier *v4l2_async_find_subdev_notifier(
+   struct v4l2_subdev *sd)
+{
+   struct v4l2_async_notifier *n;
+
+   list_for_each_entry(n, ¬ifier_list, list)
+   if (n->sd == sd)
+   return n;
+
+   return NULL;
+}
+
+/* Return true if all sub-device notifiers are complete, false otherwise. */
+static bool v4l2_async_subdev_notifiers_complete(
+   struct v4l2_async_notifier *notifier)
+{
+   struct v4l2_subdev *sd;
+
+   if (!list_empty(¬ifier->waiting))
+   return false;
+
+   list_for_each_entry(sd, ¬ifier->done, async_list) {
+   struct v4l2_async_notifier *subdev_notifier =
+   v4l2_async_find_subdev_notifier(sd);
+
+   if (!subdev_notifier)
+   continue;
+
+   if (!v4l2_async_subdev_notifiers_complete(subdev_notifier))
+   return false;
+   }
+
+   return true;
+}
+
+/* Get v4l2_device related to the notifier if one can be found. */
+static struct v4l2_device *v4l2_async_notifier_find_v4l2_dev(
+   struct v4l2_async_notifier *notifier)
+{
+   while (notifier->parent)
+   notifier = notifier->parent;
+
+   return notifier->v4l2_dev;
+}
+
+/* Test all async sub-devices in a notifier for a match. */
+static int v4l2_async_notifier_try_all_subdevs(
+   struct v4l2_async_notifier *notifier)
+{
+   struct v4l2_subdev *sd;
+
+   if (!v4l2_async_notifier_find_v4l2_dev(notifier))
+   return 0;
+
+again:
+   list_for_each_entry(sd, &subdev_list, async_list) {
+   struct v4l2_async_subdev *asd;
+   int ret;
+
+   asd = v4l2_async_find_match(notifier, sd);
+   if (!asd)
+   continue;
+
+   ret = v4l2_async_match_notify(notifier, sd, asd);
+   if (ret < 0)
+   return ret;
+
+   /*
+* v4l2_async_match_notify() may lead to registering a
+* new notifier and thus changing the async subdevs
+* list. In order to proceed safely from here, restart
+* parsing the list from the beginning.
+*/
+   goto again;
+   }
+
+   return 0;
+}
+
+/* Try completing a notifier. */
+static int v4l2_async_notifier_try_complete(
+   struct v4l2_async_notifier *notifier)
+{
+   do {
+   int ret;
+
+   /* Any local async sub-devices left? */
+   if (!list_empty(¬ifier->waiting))
+   return 0;
+
+   /*
+* Any sub-device notifiers waiting for async subdevs
+* to be bound?
+*/
+   if (!v4l2_async_subdev_notifiers_complete(notifier))
+   return 0;
+
+   /* Proceed completing the notifier */
+   ret = v4l2_async_notifier_call_complete(notifier);
+   if (ret < 0)
+   return ret;
+
+   /*
+* Obtain notifier's parent. If there is one, repeat
+  

[PATCH v12 06/26] v4l: fwnode: Support generic parsing of graph endpoints, per port

2017-09-12 Thread Sakari Ailus
This is just like like v4l2_async_notifier_parse_fwnode_endpoints but it
only parses endpoints on a single port. The behaviour is useful on devices
that have both sinks and sources, in other words only some of these should
be parsed.

Signed-off-by: Sakari Ailus 
---
 drivers/media/v4l2-core/v4l2-fwnode.c | 59 ---
 include/media/v4l2-fwnode.h   | 59 +++
 2 files changed, 113 insertions(+), 5 deletions(-)

diff --git a/drivers/media/v4l2-core/v4l2-fwnode.c 
b/drivers/media/v4l2-core/v4l2-fwnode.c
index d978f2d714ca..44ee35f6aad5 100644
--- a/drivers/media/v4l2-core/v4l2-fwnode.c
+++ b/drivers/media/v4l2-core/v4l2-fwnode.c
@@ -398,9 +398,9 @@ static int v4l2_async_notifier_fwnode_parse_endpoint(
return ret == -ENOTCONN ? 0 : ret;
 }
 
-int v4l2_async_notifier_parse_fwnode_endpoints(
+static int __v4l2_async_notifier_parse_fwnode_endpoints(
struct device *dev, struct v4l2_async_notifier *notifier,
-   size_t asd_struct_size,
+   size_t asd_struct_size, unsigned int port, bool has_port,
int (*parse_endpoint)(struct device *dev,
struct v4l2_fwnode_endpoint *vep,
struct v4l2_async_subdev *asd))
@@ -413,10 +413,25 @@ int v4l2_async_notifier_parse_fwnode_endpoints(
return -EINVAL;
 
for (fwnode = NULL; (fwnode = fwnode_graph_get_next_endpoint(
-dev_fwnode(dev), fwnode)); )
-   if (fwnode_device_is_available(
+dev_fwnode(dev), fwnode)); ) {
+   if (!fwnode_device_is_available(
fwnode_graph_get_port_parent(fwnode)))
-   max_subdevs++;
+   continue;
+
+   if (has_port) {
+   struct fwnode_endpoint ep;
+
+   ret = fwnode_graph_parse_endpoint(fwnode, &ep);
+   if (ret) {
+   fwnode_handle_put(fwnode);
+   return ret;
+   }
+
+   if (ep.port != port)
+   continue;
+   }
+   max_subdevs++;
+   }
 
/* No subdevs to add? Return here. */
if (max_subdevs == notifier->max_subdevs)
@@ -437,6 +452,17 @@ int v4l2_async_notifier_parse_fwnode_endpoints(
break;
}
 
+   if (has_port) {
+   struct fwnode_endpoint ep;
+
+   ret = fwnode_graph_parse_endpoint(fwnode, &ep);
+   if (ret)
+   break;
+
+   if (ep.port != port)
+   continue;
+   }
+
ret = v4l2_async_notifier_fwnode_parse_endpoint(
dev, notifier, fwnode, asd_struct_size, parse_endpoint);
if (ret < 0)
@@ -447,8 +473,31 @@ int v4l2_async_notifier_parse_fwnode_endpoints(
 
return ret;
 }
+
+int v4l2_async_notifier_parse_fwnode_endpoints(
+   struct device *dev, struct v4l2_async_notifier *notifier,
+   size_t asd_struct_size,
+   int (*parse_endpoint)(struct device *dev,
+   struct v4l2_fwnode_endpoint *vep,
+   struct v4l2_async_subdev *asd))
+{
+   return __v4l2_async_notifier_parse_fwnode_endpoints(
+   dev, notifier, asd_struct_size, 0, false, parse_endpoint);
+}
 EXPORT_SYMBOL_GPL(v4l2_async_notifier_parse_fwnode_endpoints);
 
+int v4l2_async_notifier_parse_fwnode_endpoints_by_port(
+   struct device *dev, struct v4l2_async_notifier *notifier,
+   size_t asd_struct_size, unsigned int port,
+   int (*parse_endpoint)(struct device *dev,
+   struct v4l2_fwnode_endpoint *vep,
+   struct v4l2_async_subdev *asd))
+{
+   return __v4l2_async_notifier_parse_fwnode_endpoints(
+   dev, notifier, asd_struct_size, port, true, parse_endpoint);
+}
+EXPORT_SYMBOL_GPL(v4l2_async_notifier_parse_fwnode_endpoints_by_port);
+
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Sakari Ailus ");
 MODULE_AUTHOR("Sylwester Nawrocki ");
diff --git a/include/media/v4l2-fwnode.h b/include/media/v4l2-fwnode.h
index 31fb77e470fa..b2eed4f33e6a 100644
--- a/include/media/v4l2-fwnode.h
+++ b/include/media/v4l2-fwnode.h
@@ -257,4 +257,63 @@ int v4l2_async_notifier_parse_fwnode_endpoints(
  struct v4l2_fwnode_endpoint *vep,
  struct v4l2_async_subdev *asd));
 
+/**
+ * v4l2_async_notifier_parse_fwnode_endpoints_by_port - Parse V4L2 fwnode
+ * endpoints of a port in a
+ * device node
+ * @dev: the device the endpoints of which are to be parsed
+ * @notifier: notifier for @dev
+ *

[PATCH v12 13/26] v4l: async: Register sub-devices before calling bound callback

2017-09-12 Thread Sakari Ailus
Register the sub-device before calling the notifier's bound callback.
Doing this the other way around is problematic as the struct v4l2_device
has not assigned for the sub-device yet and may be required by the bound
callback.

Signed-off-by: Sakari Ailus 
Acked-by: Hans Verkuil 
---
 drivers/media/v4l2-core/v4l2-async.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/media/v4l2-core/v4l2-async.c 
b/drivers/media/v4l2-core/v4l2-async.c
index c34f93593b41..7b396ff4302b 100644
--- a/drivers/media/v4l2-core/v4l2-async.c
+++ b/drivers/media/v4l2-core/v4l2-async.c
@@ -130,13 +130,13 @@ static int v4l2_async_match_notify(struct 
v4l2_async_notifier *notifier,
 {
int ret;
 
-   ret = v4l2_async_notifier_call_bound(notifier, sd, asd);
+   ret = v4l2_device_register_subdev(notifier->v4l2_dev, sd);
if (ret < 0)
return ret;
 
-   ret = v4l2_device_register_subdev(notifier->v4l2_dev, sd);
+   ret = v4l2_async_notifier_call_bound(notifier, sd, asd);
if (ret < 0) {
-   v4l2_async_notifier_call_unbind(notifier, sd, asd);
+   v4l2_device_unregister_subdev(sd);
return ret;
}
 
-- 
2.11.0



[PATCH v12 01/26] v4l: fwnode: Move KernelDoc documentation to the header

2017-09-12 Thread Sakari Ailus
In V4L2 the practice is to have the KernelDoc documentation in the header
and not in .c source code files. This consequently makes the V4L2 fwnode
function documentation part of the Media documentation build.

Also correct the link related function and argument naming in
documentation.

Signed-off-by: Sakari Ailus 
Reviewed-by: Niklas Söderlund 
Acked-by: Hans Verkuil 
Acked-by: Pavel Machek 
---
 drivers/media/v4l2-core/v4l2-fwnode.c | 75 
 include/media/v4l2-fwnode.h   | 81 ++-
 2 files changed, 80 insertions(+), 76 deletions(-)

diff --git a/drivers/media/v4l2-core/v4l2-fwnode.c 
b/drivers/media/v4l2-core/v4l2-fwnode.c
index 40b2fbfe8865..706f9e7b90f1 100644
--- a/drivers/media/v4l2-core/v4l2-fwnode.c
+++ b/drivers/media/v4l2-core/v4l2-fwnode.c
@@ -181,25 +181,6 @@ v4l2_fwnode_endpoint_parse_csi1_bus(struct fwnode_handle 
*fwnode,
vep->bus_type = V4L2_MBUS_CSI1;
 }
 
-/**
- * v4l2_fwnode_endpoint_parse() - parse all fwnode node properties
- * @fwnode: pointer to the endpoint's fwnode handle
- * @vep: pointer to the V4L2 fwnode data structure
- *
- * All properties are optional. If none are found, we don't set any flags. This
- * means the port has a static configuration and no properties have to be
- * specified explicitly. If any properties that identify the bus as parallel
- * are found and slave-mode isn't set, we set V4L2_MBUS_MASTER. Similarly, if
- * we recognise the bus as serial CSI-2 and clock-noncontinuous isn't set, we
- * set the V4L2_MBUS_CSI2_CONTINUOUS_CLOCK flag. The caller should hold a
- * reference to @fwnode.
- *
- * NOTE: This function does not parse properties the size of which is variable
- * without a low fixed limit. Please use v4l2_fwnode_endpoint_alloc_parse() in
- * new drivers instead.
- *
- * Return: 0 on success or a negative error code on failure.
- */
 int v4l2_fwnode_endpoint_parse(struct fwnode_handle *fwnode,
   struct v4l2_fwnode_endpoint *vep)
 {
@@ -239,14 +220,6 @@ int v4l2_fwnode_endpoint_parse(struct fwnode_handle 
*fwnode,
 }
 EXPORT_SYMBOL_GPL(v4l2_fwnode_endpoint_parse);
 
-/*
- * v4l2_fwnode_endpoint_free() - free the V4L2 fwnode acquired by
- * v4l2_fwnode_endpoint_alloc_parse()
- * @vep - the V4L2 fwnode the resources of which are to be released
- *
- * It is safe to call this function with NULL argument or on a V4L2 fwnode the
- * parsing of which failed.
- */
 void v4l2_fwnode_endpoint_free(struct v4l2_fwnode_endpoint *vep)
 {
if (IS_ERR_OR_NULL(vep))
@@ -257,29 +230,6 @@ void v4l2_fwnode_endpoint_free(struct v4l2_fwnode_endpoint 
*vep)
 }
 EXPORT_SYMBOL_GPL(v4l2_fwnode_endpoint_free);
 
-/**
- * v4l2_fwnode_endpoint_alloc_parse() - parse all fwnode node properties
- * @fwnode: pointer to the endpoint's fwnode handle
- *
- * All properties are optional. If none are found, we don't set any flags. This
- * means the port has a static configuration and no properties have to be
- * specified explicitly. If any properties that identify the bus as parallel
- * are found and slave-mode isn't set, we set V4L2_MBUS_MASTER. Similarly, if
- * we recognise the bus as serial CSI-2 and clock-noncontinuous isn't set, we
- * set the V4L2_MBUS_CSI2_CONTINUOUS_CLOCK flag. The caller should hold a
- * reference to @fwnode.
- *
- * v4l2_fwnode_endpoint_alloc_parse() has two important differences to
- * v4l2_fwnode_endpoint_parse():
- *
- * 1. It also parses variable size data.
- *
- * 2. The memory it has allocated to store the variable size data must be freed
- *using v4l2_fwnode_endpoint_free() when no longer needed.
- *
- * Return: Pointer to v4l2_fwnode_endpoint if successful, on an error pointer
- * on error.
- */
 struct v4l2_fwnode_endpoint *v4l2_fwnode_endpoint_alloc_parse(
struct fwnode_handle *fwnode)
 {
@@ -322,24 +272,6 @@ struct v4l2_fwnode_endpoint 
*v4l2_fwnode_endpoint_alloc_parse(
 }
 EXPORT_SYMBOL_GPL(v4l2_fwnode_endpoint_alloc_parse);
 
-/**
- * v4l2_fwnode_endpoint_parse_link() - parse a link between two endpoints
- * @__fwnode: pointer to the endpoint's fwnode at the local end of the link
- * @link: pointer to the V4L2 fwnode link data structure
- *
- * Fill the link structure with the local and remote nodes and port numbers.
- * The local_node and remote_node fields are set to point to the local and
- * remote port's parent nodes respectively (the port parent node being the
- * parent node of the port node if that node isn't a 'ports' node, or the
- * grand-parent node of the port node otherwise).
- *
- * A reference is taken to both the local and remote nodes, the caller must use
- * v4l2_fwnode_endpoint_put_link() to drop the references when done with the
- * link.
- *
- * Return: 0 on success, or -ENOLINK if the remote endpoint fwnode can't be
- * found.
- */
 int v4l2_fwnode_parse_link(struct fwnode_handle *__fwnode,
   struct v4l2_fwnode_link *link)
 {
@@ -374,13 +306,6 @@ int v4l2_fwnode_p

[PATCH v12 04/26] v4l: async: Add V4L2 async documentation to the documentation build

2017-09-12 Thread Sakari Ailus
The V4L2 async wasn't part of the documentation build. Fix this.

Signed-off-by: Sakari Ailus 
Reviewed-by: Niklas Söderlund 
Acked-by: Hans Verkuil 
Reviewed-by: Laurent Pinchart 
---
 Documentation/media/kapi/v4l2-async.rst | 3 +++
 Documentation/media/kapi/v4l2-core.rst  | 1 +
 2 files changed, 4 insertions(+)
 create mode 100644 Documentation/media/kapi/v4l2-async.rst

diff --git a/Documentation/media/kapi/v4l2-async.rst 
b/Documentation/media/kapi/v4l2-async.rst
new file mode 100644
index ..523ff9eb09a0
--- /dev/null
+++ b/Documentation/media/kapi/v4l2-async.rst
@@ -0,0 +1,3 @@
+V4L2 async kAPI
+^^^
+.. kernel-doc:: include/media/v4l2-async.h
diff --git a/Documentation/media/kapi/v4l2-core.rst 
b/Documentation/media/kapi/v4l2-core.rst
index c7434f38fd9c..5cf292037a48 100644
--- a/Documentation/media/kapi/v4l2-core.rst
+++ b/Documentation/media/kapi/v4l2-core.rst
@@ -19,6 +19,7 @@ Video4Linux devices
 v4l2-mc
 v4l2-mediabus
 v4l2-mem2mem
+v4l2-async
 v4l2-fwnode
 v4l2-rect
 v4l2-tuner
-- 
2.11.0



[PATCH v12 03/26] v4l: async: Use more intuitive names for internal functions

2017-09-12 Thread Sakari Ailus
Rename internal functions to make the names of the functions better
describe what they do.

Old nameNew name
v4l2_async_test_notify  v4l2_async_match_notify
v4l2_async_belongs  v4l2_async_find_match

Signed-off-by: Sakari Ailus 
Acked-by: Hans Verkuil 
Acked-by: Pavel Machek 
Reviewed-by: Laurent Pinchart 
---
 drivers/media/v4l2-core/v4l2-async.c | 19 ++-
 1 file changed, 10 insertions(+), 9 deletions(-)

diff --git a/drivers/media/v4l2-core/v4l2-async.c 
b/drivers/media/v4l2-core/v4l2-async.c
index e109d9da4653..831f185ecd47 100644
--- a/drivers/media/v4l2-core/v4l2-async.c
+++ b/drivers/media/v4l2-core/v4l2-async.c
@@ -60,8 +60,8 @@ static LIST_HEAD(subdev_list);
 static LIST_HEAD(notifier_list);
 static DEFINE_MUTEX(list_lock);
 
-static struct v4l2_async_subdev *v4l2_async_belongs(struct v4l2_async_notifier 
*notifier,
-   struct v4l2_subdev *sd)
+static struct v4l2_async_subdev *v4l2_async_find_match(
+   struct v4l2_async_notifier *notifier, struct v4l2_subdev *sd)
 {
bool (*match)(struct v4l2_subdev *, struct v4l2_async_subdev *);
struct v4l2_async_subdev *asd;
@@ -95,9 +95,9 @@ static struct v4l2_async_subdev *v4l2_async_belongs(struct 
v4l2_async_notifier *
return NULL;
 }
 
-static int v4l2_async_test_notify(struct v4l2_async_notifier *notifier,
- struct v4l2_subdev *sd,
- struct v4l2_async_subdev *asd)
+static int v4l2_async_match_notify(struct v4l2_async_notifier *notifier,
+  struct v4l2_subdev *sd,
+  struct v4l2_async_subdev *asd)
 {
int ret;
 
@@ -175,11 +175,11 @@ int v4l2_async_notifier_register(struct v4l2_device 
*v4l2_dev,
list_for_each_entry_safe(sd, tmp, &subdev_list, async_list) {
int ret;
 
-   asd = v4l2_async_belongs(notifier, sd);
+   asd = v4l2_async_find_match(notifier, sd);
if (!asd)
continue;
 
-   ret = v4l2_async_test_notify(notifier, sd, asd);
+   ret = v4l2_async_match_notify(notifier, sd, asd);
if (ret < 0) {
mutex_unlock(&list_lock);
return ret;
@@ -236,9 +236,10 @@ int v4l2_async_register_subdev(struct v4l2_subdev *sd)
INIT_LIST_HEAD(&sd->async_list);
 
list_for_each_entry(notifier, ¬ifier_list, list) {
-   struct v4l2_async_subdev *asd = v4l2_async_belongs(notifier, 
sd);
+   struct v4l2_async_subdev *asd = v4l2_async_find_match(notifier,
+ sd);
if (asd) {
-   int ret = v4l2_async_test_notify(notifier, sd, asd);
+   int ret = v4l2_async_match_notify(notifier, sd, asd);
mutex_unlock(&list_lock);
return ret;
}
-- 
2.11.0



[PATCH v12 17/26] dt: bindings: Add lens-focus binding for image sensors

2017-09-12 Thread Sakari Ailus
The lens-focus property contains a phandle to the lens voice coil driver
that is associated to the sensor; typically both are contained in the same
camera module.

Signed-off-by: Sakari Ailus 
Acked-by: Pavel Machek 
Reviewed-by: Sebastian Reichel 
Acked-by: Rob Herring 
Acked-by: Hans Verkuil 
---
 Documentation/devicetree/bindings/media/video-interfaces.txt | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/Documentation/devicetree/bindings/media/video-interfaces.txt 
b/Documentation/devicetree/bindings/media/video-interfaces.txt
index fdba30479b47..b535bdde861c 100644
--- a/Documentation/devicetree/bindings/media/video-interfaces.txt
+++ b/Documentation/devicetree/bindings/media/video-interfaces.txt
@@ -74,6 +74,8 @@ Optional properties
 - flash-leds: An array of phandles, each referring to a flash LED, a sub-node
   of the LED driver device node.
 
+- lens-focus: A phandle to the node of the focus lens controller.
+
 
 Optional endpoint properties
 
-- 
2.11.0



[PATCH v12 07/26] omap3isp: Use generic parser for parsing fwnode endpoints

2017-09-12 Thread Sakari Ailus
Instead of using driver implementation, use
v4l2_async_notifier_parse_fwnode_endpoints() to parse the fwnode endpoints
of the device.

Signed-off-by: Sakari Ailus 
Acked-by: Hans Verkuil 
---
 drivers/media/platform/omap3isp/isp.c | 115 +++---
 drivers/media/platform/omap3isp/isp.h |   5 +-
 2 files changed, 37 insertions(+), 83 deletions(-)

diff --git a/drivers/media/platform/omap3isp/isp.c 
b/drivers/media/platform/omap3isp/isp.c
index 1a428fe9f070..a546cf774d40 100644
--- a/drivers/media/platform/omap3isp/isp.c
+++ b/drivers/media/platform/omap3isp/isp.c
@@ -2001,6 +2001,7 @@ static int isp_remove(struct platform_device *pdev)
__omap3isp_put(isp, false);
 
media_entity_enum_cleanup(&isp->crashed);
+   v4l2_async_notifier_release(&isp->notifier);
 
return 0;
 }
@@ -2011,44 +2012,41 @@ enum isp_of_phy {
ISP_OF_PHY_CSIPHY2,
 };
 
-static int isp_fwnode_parse(struct device *dev, struct fwnode_handle *fwnode,
-   struct isp_async_subdev *isd)
+static int isp_fwnode_parse(struct device *dev,
+   struct v4l2_fwnode_endpoint *vep,
+   struct v4l2_async_subdev *asd)
 {
+   struct isp_async_subdev *isd =
+   container_of(asd, struct isp_async_subdev, asd);
struct isp_bus_cfg *buscfg = &isd->bus;
-   struct v4l2_fwnode_endpoint vep;
-   unsigned int i;
-   int ret;
bool csi1 = false;
-
-   ret = v4l2_fwnode_endpoint_parse(fwnode, &vep);
-   if (ret)
-   return ret;
+   unsigned int i;
 
dev_dbg(dev, "parsing endpoint %pOF, interface %u\n",
-   to_of_node(fwnode), vep.base.port);
+   to_of_node(vep->base.local_fwnode), vep->base.port);
 
-   switch (vep.base.port) {
+   switch (vep->base.port) {
case ISP_OF_PHY_PARALLEL:
buscfg->interface = ISP_INTERFACE_PARALLEL;
buscfg->bus.parallel.data_lane_shift =
-   vep.bus.parallel.data_shift;
+   vep->bus.parallel.data_shift;
buscfg->bus.parallel.clk_pol =
-   !!(vep.bus.parallel.flags
+   !!(vep->bus.parallel.flags
   & V4L2_MBUS_PCLK_SAMPLE_FALLING);
buscfg->bus.parallel.hs_pol =
-   !!(vep.bus.parallel.flags & V4L2_MBUS_VSYNC_ACTIVE_LOW);
+   !!(vep->bus.parallel.flags & 
V4L2_MBUS_VSYNC_ACTIVE_LOW);
buscfg->bus.parallel.vs_pol =
-   !!(vep.bus.parallel.flags & V4L2_MBUS_HSYNC_ACTIVE_LOW);
+   !!(vep->bus.parallel.flags & 
V4L2_MBUS_HSYNC_ACTIVE_LOW);
buscfg->bus.parallel.fld_pol =
-   !!(vep.bus.parallel.flags & V4L2_MBUS_FIELD_EVEN_LOW);
+   !!(vep->bus.parallel.flags & V4L2_MBUS_FIELD_EVEN_LOW);
buscfg->bus.parallel.data_pol =
-   !!(vep.bus.parallel.flags & V4L2_MBUS_DATA_ACTIVE_LOW);
-   buscfg->bus.parallel.bt656 = vep.bus_type == V4L2_MBUS_BT656;
+   !!(vep->bus.parallel.flags & V4L2_MBUS_DATA_ACTIVE_LOW);
+   buscfg->bus.parallel.bt656 = vep->bus_type == V4L2_MBUS_BT656;
break;
 
case ISP_OF_PHY_CSIPHY1:
case ISP_OF_PHY_CSIPHY2:
-   switch (vep.bus_type) {
+   switch (vep->bus_type) {
case V4L2_MBUS_CCP2:
case V4L2_MBUS_CSI1:
dev_dbg(dev, "CSI-1/CCP-2 configuration\n");
@@ -2060,11 +2058,11 @@ static int isp_fwnode_parse(struct device *dev, struct 
fwnode_handle *fwnode,
break;
default:
dev_err(dev, "unsupported bus type %u\n",
-   vep.bus_type);
+   vep->bus_type);
return -EINVAL;
}
 
-   switch (vep.base.port) {
+   switch (vep->base.port) {
case ISP_OF_PHY_CSIPHY1:
if (csi1)
buscfg->interface = ISP_INTERFACE_CCP2B_PHY1;
@@ -2080,47 +2078,47 @@ static int isp_fwnode_parse(struct device *dev, struct 
fwnode_handle *fwnode,
}
if (csi1) {
buscfg->bus.ccp2.lanecfg.clk.pos =
-   vep.bus.mipi_csi1.clock_lane;
+   vep->bus.mipi_csi1.clock_lane;
buscfg->bus.ccp2.lanecfg.clk.pol =
-   vep.bus.mipi_csi1.lane_polarity[0];
+   vep->bus.mipi_csi1.lane_polarity[0];
dev_dbg(dev, "clock lane polarity %u, pos %u\n",
buscfg->bus.ccp2.lanecfg.clk.pol,
buscfg->bus.ccp2.lanecfg.clk.pos);
 
   

[PATCH v12 19/26] v4l: fwnode: Add a helper function to obtain device / interger references

2017-09-12 Thread Sakari Ailus
v4l2_fwnode_reference_parse_int_prop() will find an fwnode such that under
the device's own fwnode, it will follow child fwnodes with the given
property -- value pair and return the resulting fwnode.

Signed-off-by: Sakari Ailus 
---
 drivers/media/v4l2-core/v4l2-fwnode.c | 145 ++
 1 file changed, 145 insertions(+)

diff --git a/drivers/media/v4l2-core/v4l2-fwnode.c 
b/drivers/media/v4l2-core/v4l2-fwnode.c
index a32473f95be1..a07599a8f647 100644
--- a/drivers/media/v4l2-core/v4l2-fwnode.c
+++ b/drivers/media/v4l2-core/v4l2-fwnode.c
@@ -567,6 +567,151 @@ static int v4l2_fwnode_reference_parse(
return ret;
 }
 
+/*
+ * v4l2_fwnode_reference_get_int_prop - parse a reference with integer
+ * arguments
+ * @dev: struct device pointer
+ * @notifier: notifier for @dev
+ * @prop: the name of the property
+ * @props: the array of integer property names
+ * @nprops: the number of integer properties
+ *
+ * Find fwnodes referred to by a property @prop, then under that iteratively
+ * follow each child node which has a property the value matches the integer
+ * argument at an index.
+ *
+ * Return: 0 on success
+ *-ENOENT if no entries (or the property itself) were found
+ *-EINVAL if property parsing otherwisefailed
+ *-ENOMEM if memory allocation failed
+ */
+static struct fwnode_handle *v4l2_fwnode_reference_get_int_prop(
+   struct fwnode_handle *fwnode, const char *prop, unsigned int index,
+   const char **props, unsigned int nprops)
+{
+   struct fwnode_reference_args fwnode_args;
+   unsigned int *args = fwnode_args.args;
+   struct fwnode_handle *child;
+   int ret;
+
+   /*
+* Obtain remote fwnode as well as the integer arguments.
+*
+* To-do: handle -ENODATA when "device property: Align return
+* codes of acpi_fwnode_get_reference_with_args" is merged.
+*/
+   ret = fwnode_property_get_reference_args(fwnode, prop, NULL, nprops,
+index, &fwnode_args);
+   if (ret)
+   return ERR_PTR(ret == -ENODATA ? -ENOENT : ret);
+
+   /*
+* Find a node in the tree under the referred fwnode corresponding the
+* integer arguments.
+*/
+   fwnode = fwnode_args.fwnode;
+   while (nprops) {
+   u32 val;
+
+   /* Loop over all child nodes under fwnode. */
+   fwnode_for_each_child_node(fwnode, child) {
+   if (fwnode_property_read_u32(child, *props, &val))
+   continue;
+
+   /* Found property, see if its value matches. */
+   if (val == *args)
+   break;
+   }
+
+   fwnode_handle_put(fwnode);
+
+   /* No property found; return an error here. */
+   if (!child) {
+   fwnode = ERR_PTR(-ENOENT);
+   break;
+   }
+
+   props++;
+   args++;
+   fwnode = child;
+   nprops--;
+   }
+
+   return fwnode;
+}
+
+/*
+ * v4l2_fwnode_reference_parse_int_props - parse references for async 
sub-devices
+ * @dev: struct device pointer
+ * @notifier: notifier for @dev
+ * @prop: the name of the property
+ * @props: the array of integer property names
+ * @nprops: the number of integer properties
+ *
+ * Use v4l2_fwnode_reference_get_int_prop to find fwnodes through reference in
+ * property @prop with integer arguments with child nodes matching in 
properties
+ * @props. Then, set up V4L2 async sub-devices for those fwnodes in the 
notifier
+ * accordingly.
+ *
+ * While it is technically possible to use this function on DT, it is only
+ * meaningful on ACPI. On Device tree you can refer to any node in the tree but
+ * on ACPI the references are limited to devices.
+ *
+ * Return: 0 on success
+ *-ENOENT if no entries (or the property itself) were found
+ *-EINVAL if property parsing otherwisefailed
+ *-ENOMEM if memory allocation failed
+ */
+static int v4l2_fwnode_reference_parse_int_props(
+   struct device *dev, struct v4l2_async_notifier *notifier,
+   const char *prop, const char **props, unsigned int nprops)
+{
+   struct fwnode_handle *fwnode;
+   unsigned int index;
+   int ret;
+
+   for (index = 0; !IS_ERR((fwnode = v4l2_fwnode_reference_get_int_prop(
+dev_fwnode(dev), prop, index, props,
+nprops))); index++)
+   fwnode_handle_put(fwnode);
+
+   if (PTR_ERR(fwnode) != -ENOENT)
+   return PTR_ERR(fwnode);
+
+   ret = v4l2_async_notifier_realloc(notifier,
+ notifier->num_subdevs + index);
+   if (ret)
+   return -ENOMEM;
+
+   for (index = 0; !IS_ERR

[PATCH v12 18/26] v4l: fwnode: Add a helper function for parsing generic references

2017-09-12 Thread Sakari Ailus
Add function v4l2_fwnode_reference_count() for counting external
references and v4l2_fwnode_reference_parse() for parsing them as async
sub-devices.

This can be done on e.g. flash or lens async sub-devices that are not part
of but are associated with a sensor.

struct v4l2_async_notifier.max_subdevs field is added to contain the
maximum number of sub-devices in a notifier to reflect the memory
allocated for the subdevs array.

Signed-off-by: Sakari Ailus 
---
 drivers/media/v4l2-core/v4l2-fwnode.c | 69 +++
 1 file changed, 69 insertions(+)

diff --git a/drivers/media/v4l2-core/v4l2-fwnode.c 
b/drivers/media/v4l2-core/v4l2-fwnode.c
index 44ee35f6aad5..a32473f95be1 100644
--- a/drivers/media/v4l2-core/v4l2-fwnode.c
+++ b/drivers/media/v4l2-core/v4l2-fwnode.c
@@ -498,6 +498,75 @@ int v4l2_async_notifier_parse_fwnode_endpoints_by_port(
 }
 EXPORT_SYMBOL_GPL(v4l2_async_notifier_parse_fwnode_endpoints_by_port);
 
+/*
+ * v4l2_fwnode_reference_parse - parse references for async sub-devices
+ * @dev: the device node the properties of which are parsed for references
+ * @notifier: the async notifier where the async subdevs will be added
+ * @prop: the name of the property
+ *
+ * Return: 0 on success
+ *-ENOENT if no entries were found
+ *-ENOMEM if memory allocation failed
+ *-EINVAL if property parsing failed
+ */
+static int v4l2_fwnode_reference_parse(
+   struct device *dev, struct v4l2_async_notifier *notifier,
+   const char *prop)
+{
+   struct fwnode_reference_args args;
+   unsigned int index;
+   int ret;
+
+   for (index = 0;
+!(ret = fwnode_property_get_reference_args(
+  dev_fwnode(dev), prop, NULL, 0, index, &args));
+index++)
+   fwnode_handle_put(args.fwnode);
+
+   if (!index)
+   return -ENOENT;
+
+   /*
+* To-do: handle -ENODATA when "device property: Align return
+* codes of acpi_fwnode_get_reference_with_args" is merged.
+*/
+   if (ret != -ENOENT && ret != -ENODATA)
+   return ret;
+
+   ret = v4l2_async_notifier_realloc(notifier,
+ notifier->num_subdevs + index);
+   if (ret)
+   return ret;
+
+   for (index = 0; !fwnode_property_get_reference_args(
+dev_fwnode(dev), prop, NULL, 0, index, &args);
+index++) {
+   struct v4l2_async_subdev *asd;
+
+   if (WARN_ON(notifier->num_subdevs >= notifier->max_subdevs)) {
+   ret = -EINVAL;
+   goto error;
+   }
+
+   asd = kzalloc(sizeof(*asd), GFP_KERNEL);
+   if (!asd) {
+   ret = -ENOMEM;
+   goto error;
+   }
+
+   notifier->subdevs[notifier->num_subdevs] = asd;
+   asd->match.fwnode.fwnode = args.fwnode;
+   asd->match_type = V4L2_ASYNC_MATCH_FWNODE;
+   notifier->num_subdevs++;
+   }
+
+   return 0;
+
+error:
+   fwnode_handle_put(args.fwnode);
+   return ret;
+}
+
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Sakari Ailus ");
 MODULE_AUTHOR("Sylwester Nawrocki ");
-- 
2.11.0



[PATCH v12 20/26] v4l: fwnode: Add convenience function for parsing common external refs

2017-09-12 Thread Sakari Ailus
Add v4l2_fwnode_parse_reference_sensor_common for parsing common
sensor properties that refer to adjacent devices such as flash or lens
driver chips.

As this is an association only, there's little a regular driver needs to
know about these devices as such.

Signed-off-by: Sakari Ailus 
Acked-by: Hans Verkuil 
Acked-by: Pavel Machek 
---
 drivers/media/v4l2-core/v4l2-fwnode.c | 35 +++
 include/media/v4l2-async.h|  3 ++-
 include/media/v4l2-fwnode.h   | 21 +
 3 files changed, 58 insertions(+), 1 deletion(-)

diff --git a/drivers/media/v4l2-core/v4l2-fwnode.c 
b/drivers/media/v4l2-core/v4l2-fwnode.c
index a07599a8f647..0a1a784b11a8 100644
--- a/drivers/media/v4l2-core/v4l2-fwnode.c
+++ b/drivers/media/v4l2-core/v4l2-fwnode.c
@@ -712,6 +712,41 @@ static int v4l2_fwnode_reference_parse_int_props(
return ret;
 }
 
+int v4l2_async_notifier_parse_fwnode_sensor_common(
+   struct device *dev, struct v4l2_async_notifier *notifier)
+{
+   static const char *led_props[] = { "led" };
+   static const struct {
+   const char *name;
+   const char **props;
+   unsigned int nprops;
+   } props[] = {
+   { "flash-leds", led_props, ARRAY_SIZE(led_props) },
+   { "lens-focus", NULL, 0 },
+   };
+   unsigned int i;
+
+   for (i = 0; i < ARRAY_SIZE(props); i++) {
+   int ret;
+
+   if (props[i].props && is_acpi_node(dev_fwnode(dev)))
+   ret = v4l2_fwnode_reference_parse_int_props(
+   dev, notifier, props[i].name,
+   props[i].props, props[i].nprops);
+   else
+   ret = v4l2_fwnode_reference_parse(
+   dev, notifier, props[i].name);
+   if (ret && ret != -ENOENT) {
+   dev_warn(dev, "parsing property \"%s\" failed (%d)\n",
+props[i].name, ret);
+   return ret;
+   }
+   }
+
+   return 0;
+}
+EXPORT_SYMBOL_GPL(v4l2_async_notifier_parse_fwnode_sensor_common);
+
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Sakari Ailus ");
 MODULE_AUTHOR("Sylwester Nawrocki ");
diff --git a/include/media/v4l2-async.h b/include/media/v4l2-async.h
index a13803a6371d..378e20e3b44d 100644
--- a/include/media/v4l2-async.h
+++ b/include/media/v4l2-async.h
@@ -155,7 +155,8 @@ void v4l2_async_notifier_unregister(struct 
v4l2_async_notifier *notifier);
  * Release memory resources related to a notifier, including the async
  * sub-devices allocated for the purposes of the notifier. The user is
  * responsible for releasing the notifier's resources after calling
- * @v4l2_async_notifier_parse_fwnode_endpoints.
+ * @v4l2_async_notifier_parse_fwnode_endpoints or
+ * @v4l2_fwnode_reference_parse_sensor_common.
  *
  * There is no harm from calling v4l2_async_notifier_release in other
  * cases as long as its memory has been zeroed after it has been
diff --git a/include/media/v4l2-fwnode.h b/include/media/v4l2-fwnode.h
index b2eed4f33e6a..5791355401bd 100644
--- a/include/media/v4l2-fwnode.h
+++ b/include/media/v4l2-fwnode.h
@@ -316,4 +316,25 @@ int v4l2_async_notifier_parse_fwnode_endpoints_by_port(
  struct v4l2_fwnode_endpoint *vep,
  struct v4l2_async_subdev *asd));
 
+/**
+ * v4l2_fwnode_reference_parse_sensor_common - parse common references on
+ *sensors for async sub-devices
+ * @dev: the device node the properties of which are parsed for references
+ * @notifier: the async notifier where the async subdevs will be added
+ *
+ * Parse common sensor properties for remote devices related to the
+ * sensor and set up async sub-devices for them.
+ *
+ * Any notifier populated using this function must be released with a call to
+ * v4l2_async_notifier_release() after it has been unregistered and the async
+ * sub-devices are no longer in use, even in the case the function returned an
+ * error.
+ *
+ * Return: 0 on success
+ *-ENOMEM if memory allocation failed
+ *-EINVAL if property parsing failed
+ */
+int v4l2_async_notifier_parse_fwnode_sensor_common(
+   struct device *dev, struct v4l2_async_notifier *notifier);
+
 #endif /* _V4L2_FWNODE_H */
-- 
2.11.0



[PATCH v12 25/26] ov13858: Add support for flash and lens devices

2017-09-12 Thread Sakari Ailus
Parse async sub-devices by using
v4l2_subdev_fwnode_reference_parse_sensor_common().

Signed-off-by: Sakari Ailus 
Acked-by: Hans Verkuil 
---
 drivers/media/i2c/ov13858.c | 26 +++---
 1 file changed, 23 insertions(+), 3 deletions(-)

diff --git a/drivers/media/i2c/ov13858.c b/drivers/media/i2c/ov13858.c
index af7af0d14c69..a8a9fb0a1756 100644
--- a/drivers/media/i2c/ov13858.c
+++ b/drivers/media/i2c/ov13858.c
@@ -18,6 +18,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #define OV13858_REG_VALUE_08BIT1
 #define OV13858_REG_VALUE_16BIT2
@@ -1028,6 +1029,7 @@ static const struct ov13858_mode supported_modes[] = {
 struct ov13858 {
struct v4l2_subdev sd;
struct media_pad pad;
+   struct v4l2_async_notifier notifier;
 
struct v4l2_ctrl_handler ctrl_handler;
/* V4L2 Controls */
@@ -1715,6 +1717,11 @@ static int ov13858_probe(struct i2c_client *client,
if (!ov13858)
return -ENOMEM;
 
+   ret = v4l2_async_notifier_parse_fwnode_sensor_common(
+   &client->dev, &ov13858->notifier);
+   if (ret < 0)
+   return ret;
+
/* Initialize subdev */
v4l2_i2c_subdev_init(&ov13858->sd, client, &ov13858_subdev_ops);
 
@@ -1722,7 +1729,7 @@ static int ov13858_probe(struct i2c_client *client,
ret = ov13858_identify_module(ov13858);
if (ret) {
dev_err(&client->dev, "failed to find sensor: %d\n", ret);
-   return ret;
+   goto error_notifier_release;
}
 
/* Set default mode to max resolution */
@@ -1730,7 +1737,7 @@ static int ov13858_probe(struct i2c_client *client,
 
ret = ov13858_init_controls(ov13858);
if (ret)
-   return ret;
+   goto error_notifier_release;
 
/* Initialize subdev */
ov13858->sd.internal_ops = &ov13858_internal_ops;
@@ -1746,9 +1753,14 @@ static int ov13858_probe(struct i2c_client *client,
goto error_handler_free;
}
 
+   ret = v4l2_async_subdev_notifier_register(&ov13858->sd,
+ &ov13858->notifier);
+   if (ret)
+   goto error_media_entity;
+
ret = v4l2_async_register_subdev(&ov13858->sd);
if (ret < 0)
-   goto error_media_entity;
+   goto error_notifier_unregister;
 
/*
 * Device is already turned on by i2c-core with ACPI domain PM.
@@ -1761,11 +1773,17 @@ static int ov13858_probe(struct i2c_client *client,
 
return 0;
 
+error_notifier_unregister:
+   v4l2_async_notifier_unregister(&ov13858->notifier);
+
 error_media_entity:
media_entity_cleanup(&ov13858->sd.entity);
 
 error_handler_free:
ov13858_free_controls(ov13858);
+
+error_notifier_release:
+   v4l2_async_notifier_release(&ov13858->notifier);
dev_err(&client->dev, "%s failed:%d\n", __func__, ret);
 
return ret;
@@ -1777,6 +1795,8 @@ static int ov13858_remove(struct i2c_client *client)
struct ov13858 *ov13858 = to_ov13858(sd);
 
v4l2_async_unregister_subdev(sd);
+   v4l2_async_notifier_unregister(&ov13858->notifier);
+   v4l2_async_notifier_release(&ov13858->notifier);
media_entity_cleanup(&sd->entity);
ov13858_free_controls(ov13858);
 
-- 
2.11.0



[PATCH v12 21/26] dt: bindings: smiapp: Document lens-focus and flash-leds properties

2017-09-12 Thread Sakari Ailus
Document optional lens-focus and flash-leds properties for the smiapp
driver.

Signed-off-by: Sakari Ailus 
Acked-by: Hans Verkuil 
Acked-by: Pavel Machek 
---
 Documentation/devicetree/bindings/media/i2c/nokia,smia.txt | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/Documentation/devicetree/bindings/media/i2c/nokia,smia.txt 
b/Documentation/devicetree/bindings/media/i2c/nokia,smia.txt
index 855e1faf73e2..33f10a94c381 100644
--- a/Documentation/devicetree/bindings/media/i2c/nokia,smia.txt
+++ b/Documentation/devicetree/bindings/media/i2c/nokia,smia.txt
@@ -27,6 +27,8 @@ Optional properties
 - nokia,nvm-size: The size of the NVM, in bytes. If the size is not given,
   the NVM contents will not be read.
 - reset-gpios: XSHUTDOWN GPIO
+- flash-leds: See ../video-interfaces.txt
+- lens-focus: See ../video-interfaces.txt
 
 
 Endpoint node mandatory properties
-- 
2.11.0



[PATCH v12 22/26] smiapp: Add support for flash and lens devices

2017-09-12 Thread Sakari Ailus
Parse async sub-devices by using
v4l2_subdev_fwnode_reference_parse_sensor_common().

These types devices aren't directly related to the sensor, but are
nevertheless handled by the smiapp driver due to the relationship of these
component to the main part of the camera module --- the sensor.

This does not yet address providing the user space with information on how
to associate the sensor or lens devices but the kernel now has the
necessary information to do that.

Signed-off-by: Sakari Ailus 
Acked-by: Hans Verkuil 
Acked-by: Pavel Machek 
---
 drivers/media/i2c/smiapp/smiapp-core.c | 38 +++---
 drivers/media/i2c/smiapp/smiapp.h  |  4 +++-
 2 files changed, 33 insertions(+), 9 deletions(-)

diff --git a/drivers/media/i2c/smiapp/smiapp-core.c 
b/drivers/media/i2c/smiapp/smiapp-core.c
index 700f433261d0..a4735a96ea41 100644
--- a/drivers/media/i2c/smiapp/smiapp-core.c
+++ b/drivers/media/i2c/smiapp/smiapp-core.c
@@ -31,7 +31,7 @@
 #include 
 #include 
 #include 
-#include 
+#include 
 #include 
 #include 
 
@@ -2887,17 +2887,24 @@ static int smiapp_probe(struct i2c_client *client,
v4l2_i2c_subdev_init(&sensor->src->sd, client, &smiapp_ops);
sensor->src->sd.internal_ops = &smiapp_internal_src_ops;
 
+   rval = v4l2_async_notifier_parse_fwnode_sensor_common(
+   &client->dev, &sensor->notifier);
+   if (rval < 0)
+   return rval;
+
sensor->vana = devm_regulator_get(&client->dev, "vana");
if (IS_ERR(sensor->vana)) {
dev_err(&client->dev, "could not get regulator for vana\n");
-   return PTR_ERR(sensor->vana);
+   rval = PTR_ERR(sensor->vana);
+   goto out_release_async_notifier;
}
 
sensor->ext_clk = devm_clk_get(&client->dev, NULL);
if (IS_ERR(sensor->ext_clk)) {
dev_err(&client->dev, "could not get clock (%ld)\n",
PTR_ERR(sensor->ext_clk));
-   return -EPROBE_DEFER;
+   rval = -EPROBE_DEFER;
+   goto out_release_async_notifier;
}
 
rval = clk_set_rate(sensor->ext_clk, sensor->hwcfg->ext_clk);
@@ -2905,17 +2912,19 @@ static int smiapp_probe(struct i2c_client *client,
dev_err(&client->dev,
"unable to set clock freq to %u\n",
sensor->hwcfg->ext_clk);
-   return rval;
+   goto out_release_async_notifier;
}
 
sensor->xshutdown = devm_gpiod_get_optional(&client->dev, "xshutdown",
GPIOD_OUT_LOW);
-   if (IS_ERR(sensor->xshutdown))
-   return PTR_ERR(sensor->xshutdown);
+   if (IS_ERR(sensor->xshutdown)) {
+   rval = PTR_ERR(sensor->xshutdown);
+   goto out_release_async_notifier;
+   }
 
rval = smiapp_power_on(&client->dev);
if (rval < 0)
-   return rval;
+   goto out_release_async_notifier;
 
rval = smiapp_identify_module(sensor);
if (rval) {
@@ -3092,9 +3101,14 @@ static int smiapp_probe(struct i2c_client *client,
if (rval < 0)
goto out_media_entity_cleanup;
 
+   rval = v4l2_async_subdev_notifier_register(&sensor->src->sd,
+  &sensor->notifier);
+   if (rval)
+   goto out_media_entity_cleanup;
+
rval = v4l2_async_register_subdev(&sensor->src->sd);
if (rval < 0)
-   goto out_media_entity_cleanup;
+   goto out_unregister_async_notifier;
 
pm_runtime_set_active(&client->dev);
pm_runtime_get_noresume(&client->dev);
@@ -3105,6 +3119,9 @@ static int smiapp_probe(struct i2c_client *client,
 
return 0;
 
+out_unregister_async_notifier:
+   v4l2_async_notifier_unregister(&sensor->notifier);
+
 out_media_entity_cleanup:
media_entity_cleanup(&sensor->src->sd.entity);
 
@@ -3114,6 +3131,9 @@ static int smiapp_probe(struct i2c_client *client,
 out_power_off:
smiapp_power_off(&client->dev);
 
+out_release_async_notifier:
+   v4l2_async_notifier_release(&sensor->notifier);
+
return rval;
 }
 
@@ -3124,6 +3144,8 @@ static int smiapp_remove(struct i2c_client *client)
unsigned int i;
 
v4l2_async_unregister_subdev(subdev);
+   v4l2_async_notifier_unregister(&sensor->notifier);
+   v4l2_async_notifier_release(&sensor->notifier);
 
pm_runtime_disable(&client->dev);
if (!pm_runtime_status_suspended(&client->dev))
diff --git a/drivers/media/i2c/smiapp/smiapp.h 
b/drivers/media/i2c/smiapp/smiapp.h
index f74d695018b9..be92cb5713f4 100644
--- a/drivers/media/i2c/smiapp/smiapp.h
+++ b/drivers/media/i2c/smiapp/smiapp.h
@@ -20,9 +20,10 @@
 #define __SMIAPP_PRIV_H_
 
 #include 
+#include 
+#include 
 #include 
 #include 
-#include 
 
 #include "smiapp-pll.h"
 #include "smiapp-reg.h"
@@ -172,6 +173,7 @@ 

[PATCH v12 23/26] et8ek8: Add support for flash and lens devices

2017-09-12 Thread Sakari Ailus
From: Pavel Machek 

Parse async sub-devices by using
v4l2_subdev_fwnode_reference_parse_sensor_common().

These types devices aren't directly related to the sensor, but are
nevertheless handled by the et8ek8 driver due to the relationship of these
component to the main part of the camera module --- the sensor.

[Sakari Ailus: Rename fwnode function, check for ret < 0 only.]
Signed-off-by: Pavel Machek 
Signed-off-by: Sakari Ailus 
---
 drivers/media/i2c/et8ek8/et8ek8_driver.c | 21 -
 1 file changed, 20 insertions(+), 1 deletion(-)

diff --git a/drivers/media/i2c/et8ek8/et8ek8_driver.c 
b/drivers/media/i2c/et8ek8/et8ek8_driver.c
index c14f0fd6ded3..0ef1b8025935 100644
--- a/drivers/media/i2c/et8ek8/et8ek8_driver.c
+++ b/drivers/media/i2c/et8ek8/et8ek8_driver.c
@@ -34,10 +34,12 @@
 #include 
 #include 
 
+#include 
 #include 
 #include 
 #include 
 #include 
+#include 
 
 #include "et8ek8_reg.h"
 
@@ -46,6 +48,7 @@
 #define ET8EK8_MAX_MSG 8
 
 struct et8ek8_sensor {
+   struct v4l2_async_notifier notifier;
struct v4l2_subdev subdev;
struct media_pad pad;
struct v4l2_mbus_framefmt format;
@@ -1446,6 +1449,11 @@ static int et8ek8_probe(struct i2c_client *client,
sensor->subdev.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
sensor->subdev.internal_ops = &et8ek8_internal_ops;
 
+   ret = v4l2_async_notifier_parse_fwnode_sensor_common(
+   &client->dev, &sensor->notifier);
+   if (ret < 0)
+   goto err_release;
+
sensor->pad.flags = MEDIA_PAD_FL_SOURCE;
ret = media_entity_pads_init(&sensor->subdev.entity, 1, &sensor->pad);
if (ret < 0) {
@@ -1453,18 +1461,27 @@ static int et8ek8_probe(struct i2c_client *client,
goto err_mutex;
}
 
+   ret = v4l2_async_subdev_notifier_register(&sensor->subdev,
+ &sensor->notifier);
+   if (ret)
+   goto err_entity;
+
ret = v4l2_async_register_subdev(&sensor->subdev);
if (ret < 0)
-   goto err_entity;
+   goto err_async;
 
dev_dbg(dev, "initialized!\n");
 
return 0;
 
+err_async:
+   v4l2_async_notifier_unregister(&sensor->notifier);
 err_entity:
media_entity_cleanup(&sensor->subdev.entity);
 err_mutex:
mutex_destroy(&sensor->power_lock);
+err_release:
+   v4l2_async_notifier_release(&sensor->notifier);
return ret;
 }
 
@@ -1480,6 +1497,8 @@ static int __exit et8ek8_remove(struct i2c_client *client)
}
 
v4l2_device_unregister_subdev(&sensor->subdev);
+   v4l2_async_notifier_unregister(&sensor->notifier);
+   v4l2_async_notifier_release(&sensor->notifier);
device_remove_file(&client->dev, &dev_attr_priv_mem);
v4l2_ctrl_handler_free(&sensor->ctrl_handler);
v4l2_async_unregister_subdev(&sensor->subdev);
-- 
2.11.0



[PATCH v12 08/26] rcar-vin: Use generic parser for parsing fwnode endpoints

2017-09-12 Thread Sakari Ailus
Instead of using driver implementation, use
v4l2_async_notifier_parse_fwnode_endpoints() to parse the fwnode endpoints
of the device.

Signed-off-by: Sakari Ailus 
Acked-by: Hans Verkuil 
---
 drivers/media/platform/rcar-vin/rcar-core.c | 112 +---
 drivers/media/platform/rcar-vin/rcar-dma.c  |  10 +--
 drivers/media/platform/rcar-vin/rcar-v4l2.c |  14 ++--
 drivers/media/platform/rcar-vin/rcar-vin.h  |   4 +-
 4 files changed, 48 insertions(+), 92 deletions(-)

diff --git a/drivers/media/platform/rcar-vin/rcar-core.c 
b/drivers/media/platform/rcar-vin/rcar-core.c
index 142de447..62b4a94f9a39 100644
--- a/drivers/media/platform/rcar-vin/rcar-core.c
+++ b/drivers/media/platform/rcar-vin/rcar-core.c
@@ -21,6 +21,7 @@
 #include 
 #include 
 
+#include 
 #include 
 
 #include "rcar-vin.h"
@@ -77,14 +78,14 @@ static int rvin_digital_notify_complete(struct 
v4l2_async_notifier *notifier)
int ret;
 
/* Verify subdevices mbus format */
-   if (!rvin_mbus_supported(&vin->digital)) {
+   if (!rvin_mbus_supported(vin->digital)) {
vin_err(vin, "Unsupported media bus format for %s\n",
-   vin->digital.subdev->name);
+   vin->digital->subdev->name);
return -EINVAL;
}
 
vin_dbg(vin, "Found media bus format for %s: %d\n",
-   vin->digital.subdev->name, vin->digital.code);
+   vin->digital->subdev->name, vin->digital->code);
 
ret = v4l2_device_register_subdev_nodes(&vin->v4l2_dev);
if (ret < 0) {
@@ -103,7 +104,7 @@ static void rvin_digital_notify_unbind(struct 
v4l2_async_notifier *notifier,
 
vin_dbg(vin, "unbind digital subdev %s\n", subdev->name);
rvin_v4l2_remove(vin);
-   vin->digital.subdev = NULL;
+   vin->digital->subdev = NULL;
 }
 
 static int rvin_digital_notify_bound(struct v4l2_async_notifier *notifier,
@@ -120,117 +121,70 @@ static int rvin_digital_notify_bound(struct 
v4l2_async_notifier *notifier,
ret = rvin_find_pad(subdev, MEDIA_PAD_FL_SOURCE);
if (ret < 0)
return ret;
-   vin->digital.source_pad = ret;
+   vin->digital->source_pad = ret;
 
ret = rvin_find_pad(subdev, MEDIA_PAD_FL_SINK);
-   vin->digital.sink_pad = ret < 0 ? 0 : ret;
+   vin->digital->sink_pad = ret < 0 ? 0 : ret;
 
-   vin->digital.subdev = subdev;
+   vin->digital->subdev = subdev;
 
vin_dbg(vin, "bound subdev %s source pad: %u sink pad: %u\n",
-   subdev->name, vin->digital.source_pad,
-   vin->digital.sink_pad);
+   subdev->name, vin->digital->source_pad,
+   vin->digital->sink_pad);
 
return 0;
 }
 
-static int rvin_digitial_parse_v4l2(struct rvin_dev *vin,
-   struct device_node *ep,
-   struct v4l2_mbus_config *mbus_cfg)
+static int rvin_digital_parse_v4l2(struct device *dev,
+  struct v4l2_fwnode_endpoint *vep,
+  struct v4l2_async_subdev *asd)
 {
-   struct v4l2_fwnode_endpoint v4l2_ep;
-   int ret;
+   struct rvin_dev *vin = dev_get_drvdata(dev);
+   struct rvin_graph_entity *rvge =
+   container_of(asd, struct rvin_graph_entity, asd);
 
-   ret = v4l2_fwnode_endpoint_parse(of_fwnode_handle(ep), &v4l2_ep);
-   if (ret) {
-   vin_err(vin, "Could not parse v4l2 endpoint\n");
-   return -EINVAL;
-   }
+   if (vep->base.port || vep->base.id)
+   return -ENOTCONN;
 
-   mbus_cfg->type = v4l2_ep.bus_type;
+   rvge->mbus_cfg.type = vep->bus_type;
 
-   switch (mbus_cfg->type) {
+   switch (rvge->mbus_cfg.type) {
case V4L2_MBUS_PARALLEL:
vin_dbg(vin, "Found PARALLEL media bus\n");
-   mbus_cfg->flags = v4l2_ep.bus.parallel.flags;
+   rvge->mbus_cfg.flags = vep->bus.parallel.flags;
break;
case V4L2_MBUS_BT656:
vin_dbg(vin, "Found BT656 media bus\n");
-   mbus_cfg->flags = 0;
+   rvge->mbus_cfg.flags = 0;
break;
default:
vin_err(vin, "Unknown media bus type\n");
return -EINVAL;
}
 
-   return 0;
-}
-
-static int rvin_digital_graph_parse(struct rvin_dev *vin)
-{
-   struct device_node *ep, *np;
-   int ret;
-
-   vin->digital.asd.match.fwnode.fwnode = NULL;
-   vin->digital.subdev = NULL;
-
-   /*
-* Port 0 id 0 is local digital input, try to get it.
-* Not all instances can or will have this, that is OK
-*/
-   ep = of_graph_get_endpoint_by_regs(vin->dev->of_node, 0, 0);
-   if (!ep)
-   return 0;
-
-   np = of_graph_get_remote_port_parent(ep);
-   if (!np) {
-   vin_err(vin, "No remote parent for digital input\n");
-   o

[PATCH v12 24/26] ov5670: Add support for flash and lens devices

2017-09-12 Thread Sakari Ailus
Parse async sub-devices by using
v4l2_subdev_fwnode_reference_parse_sensor_common().

Signed-off-by: Sakari Ailus 
Acked-by: Hans Verkuil 
---
 drivers/media/i2c/ov5670.c | 33 +
 1 file changed, 25 insertions(+), 8 deletions(-)

diff --git a/drivers/media/i2c/ov5670.c b/drivers/media/i2c/ov5670.c
index 6f7a1d6d2200..a791701fa2b9 100644
--- a/drivers/media/i2c/ov5670.c
+++ b/drivers/media/i2c/ov5670.c
@@ -18,6 +18,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #define OV5670_REG_CHIP_ID 0x300a
 #define OV5670_CHIP_ID 0x005670
@@ -1807,6 +1808,7 @@ static const struct ov5670_mode supported_modes[] = {
 struct ov5670 {
struct v4l2_subdev sd;
struct media_pad pad;
+   struct v4l2_async_notifier notifier;
 
struct v4l2_ctrl_handler ctrl_handler;
/* V4L2 Controls */
@@ -2473,11 +2475,13 @@ static int ov5670_probe(struct i2c_client *client)
return -EINVAL;
 
ov5670 = devm_kzalloc(&client->dev, sizeof(*ov5670), GFP_KERNEL);
-   if (!ov5670) {
-   ret = -ENOMEM;
-   err_msg = "devm_kzalloc() error";
-   goto error_print;
-   }
+   if (!ov5670)
+   return -ENOMEM;
+
+   ret = v4l2_async_notifier_parse_fwnode_sensor_common(
+   &client->dev, &ov5670->notifier);
+   if (ret < 0)
+   return ret;
 
/* Initialize subdev */
v4l2_i2c_subdev_init(&ov5670->sd, client, &ov5670_subdev_ops);
@@ -2486,7 +2490,7 @@ static int ov5670_probe(struct i2c_client *client)
ret = ov5670_identify_module(ov5670);
if (ret) {
err_msg = "ov5670_identify_module() error";
-   goto error_print;
+   goto error_release_notifier;
}
 
mutex_init(&ov5670->mutex);
@@ -2513,11 +2517,18 @@ static int ov5670_probe(struct i2c_client *client)
goto error_handler_free;
}
 
+   ret = v4l2_async_subdev_notifier_register(&ov5670->sd,
+ &ov5670->notifier);
+   if (ret) {
+   err_msg = "can't register async notifier";
+   goto error_entity_cleanup;
+   }
+
/* Async register for subdev */
ret = v4l2_async_register_subdev(&ov5670->sd);
if (ret < 0) {
err_msg = "v4l2_async_register_subdev() error";
-   goto error_entity_cleanup;
+   goto error_unregister_notifier;
}
 
ov5670->streaming = false;
@@ -2533,6 +2544,9 @@ static int ov5670_probe(struct i2c_client *client)
 
return 0;
 
+error_unregister_notifier:
+   v4l2_async_notifier_unregister(&ov5670->notifier);
+
 error_entity_cleanup:
media_entity_cleanup(&ov5670->sd.entity);
 
@@ -2542,7 +2556,8 @@ static int ov5670_probe(struct i2c_client *client)
 error_mutex_destroy:
mutex_destroy(&ov5670->mutex);
 
-error_print:
+error_release_notifier:
+   v4l2_async_notifier_release(&ov5670->notifier);
dev_err(&client->dev, "%s: %s %d\n", __func__, err_msg, ret);
 
return ret;
@@ -2554,6 +2569,8 @@ static int ov5670_remove(struct i2c_client *client)
struct ov5670 *ov5670 = to_ov5670(sd);
 
v4l2_async_unregister_subdev(sd);
+   v4l2_async_notifier_unregister(&ov5670->notifier);
+   v4l2_async_notifier_release(&ov5670->notifier);
media_entity_cleanup(&sd->entity);
v4l2_ctrl_handler_free(sd->ctrl_handler);
mutex_destroy(&ov5670->mutex);
-- 
2.11.0



[PATCH v12 26/26] arm: dts: omap3: N9/N950: Add flash references to the camera

2017-09-12 Thread Sakari Ailus
Add flash and indicator LED phandles to the sensor node.

Signed-off-by: Sakari Ailus 
Acked-by: Hans Verkuil 
Acked-by: Pavel Machek 
---
 arch/arm/boot/dts/omap3-n9.dts   | 1 +
 arch/arm/boot/dts/omap3-n950-n9.dtsi | 4 ++--
 arch/arm/boot/dts/omap3-n950.dts | 1 +
 3 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/arch/arm/boot/dts/omap3-n9.dts b/arch/arm/boot/dts/omap3-n9.dts
index b9e58c536afd..39e35f8b8206 100644
--- a/arch/arm/boot/dts/omap3-n9.dts
+++ b/arch/arm/boot/dts/omap3-n9.dts
@@ -26,6 +26,7 @@
clocks = <&isp 0>;
clock-frequency = <960>;
nokia,nvm-size = <(16 * 64)>;
+   flash-leds = <&as3645a_flash &as3645a_indicator>;
port {
smia_1_1: endpoint {
link-frequencies = /bits/ 64 <19920 
21000 49920>;
diff --git a/arch/arm/boot/dts/omap3-n950-n9.dtsi 
b/arch/arm/boot/dts/omap3-n950-n9.dtsi
index 1b0bd72945f2..12fbb3da5fce 100644
--- a/arch/arm/boot/dts/omap3-n950-n9.dtsi
+++ b/arch/arm/boot/dts/omap3-n950-n9.dtsi
@@ -271,14 +271,14 @@
#size-cells = <0>;
reg = <0x30>;
compatible = "ams,as3645a";
-   flash@0 {
+   as3645a_flash: flash@0 {
reg = <0x0>;
flash-timeout-us = <15>;
flash-max-microamp = <32>;
led-max-microamp = <6>;
ams,input-max-microamp = <175>;
};
-   indicator@1 {
+   as3645a_indicator: indicator@1 {
reg = <0x1>;
led-max-microamp = <1>;
};
diff --git a/arch/arm/boot/dts/omap3-n950.dts b/arch/arm/boot/dts/omap3-n950.dts
index 646601a3ebd8..c354a1ed1e70 100644
--- a/arch/arm/boot/dts/omap3-n950.dts
+++ b/arch/arm/boot/dts/omap3-n950.dts
@@ -60,6 +60,7 @@
clocks = <&isp 0>;
clock-frequency = <960>;
nokia,nvm-size = <(16 * 64)>;
+   flash-leds = <&as3645a_flash &as3645a_indicator>;
port {
smia_1_1: endpoint {
link-frequencies = /bits/ 64 <21000 
33360 39840>;
-- 
2.11.0



[PATCH v12 05/26] v4l: fwnode: Support generic parsing of graph endpoints in a device

2017-09-12 Thread Sakari Ailus
The current practice is that drivers iterate over their endpoints and
parse each endpoint separately. This is very similar in a number of
drivers, implement a generic function for the job. Driver specific matters
can be taken into account in the driver specific callback.

Signed-off-by: Sakari Ailus 
Acked-by: Hans Verkuil 
---
 drivers/media/v4l2-core/v4l2-async.c  |  30 
 drivers/media/v4l2-core/v4l2-fwnode.c | 136 ++
 include/media/v4l2-async.h|  24 +-
 include/media/v4l2-fwnode.h   |  56 ++
 4 files changed, 244 insertions(+), 2 deletions(-)

diff --git a/drivers/media/v4l2-core/v4l2-async.c 
b/drivers/media/v4l2-core/v4l2-async.c
index 831f185ecd47..ad099b9bb71d 100644
--- a/drivers/media/v4l2-core/v4l2-async.c
+++ b/drivers/media/v4l2-core/v4l2-async.c
@@ -22,6 +22,7 @@
 
 #include 
 #include 
+#include 
 #include 
 
 static bool match_i2c(struct v4l2_subdev *sd, struct v4l2_async_subdev *asd)
@@ -219,6 +220,35 @@ void v4l2_async_notifier_unregister(struct 
v4l2_async_notifier *notifier)
 }
 EXPORT_SYMBOL(v4l2_async_notifier_unregister);
 
+void v4l2_async_notifier_release(struct v4l2_async_notifier *notifier)
+{
+   unsigned int i;
+
+   if (!notifier->max_subdevs)
+   return;
+
+   for (i = 0; i < notifier->num_subdevs; i++) {
+   struct v4l2_async_subdev *asd = notifier->subdevs[i];
+
+   switch (asd->match_type) {
+   case V4L2_ASYNC_MATCH_FWNODE:
+   fwnode_handle_put(asd->match.fwnode.fwnode);
+   break;
+   default:
+   WARN_ON_ONCE(1);
+   }
+
+   kfree(asd);
+   }
+
+   notifier->max_subdevs = 0;
+   notifier->num_subdevs = 0;
+
+   kvfree(notifier->subdevs);
+   notifier->subdevs = NULL;
+}
+EXPORT_SYMBOL_GPL(v4l2_async_notifier_release);
+
 int v4l2_async_register_subdev(struct v4l2_subdev *sd)
 {
struct v4l2_async_notifier *notifier;
diff --git a/drivers/media/v4l2-core/v4l2-fwnode.c 
b/drivers/media/v4l2-core/v4l2-fwnode.c
index 706f9e7b90f1..d978f2d714ca 100644
--- a/drivers/media/v4l2-core/v4l2-fwnode.c
+++ b/drivers/media/v4l2-core/v4l2-fwnode.c
@@ -19,6 +19,7 @@
  */
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -26,6 +27,7 @@
 #include 
 #include 
 
+#include 
 #include 
 
 enum v4l2_fwnode_bus_type {
@@ -313,6 +315,140 @@ void v4l2_fwnode_put_link(struct v4l2_fwnode_link *link)
 }
 EXPORT_SYMBOL_GPL(v4l2_fwnode_put_link);
 
+static int v4l2_async_notifier_realloc(struct v4l2_async_notifier *notifier,
+  unsigned int max_subdevs)
+{
+   struct v4l2_async_subdev **subdevs;
+
+   if (max_subdevs <= notifier->max_subdevs)
+   return 0;
+
+   subdevs = kvmalloc_array(
+   max_subdevs, sizeof(*notifier->subdevs),
+   GFP_KERNEL | __GFP_ZERO);
+   if (!subdevs)
+   return -ENOMEM;
+
+   if (notifier->subdevs) {
+   memcpy(subdevs, notifier->subdevs,
+  sizeof(*subdevs) * notifier->num_subdevs);
+
+   kvfree(notifier->subdevs);
+   }
+
+   notifier->subdevs = subdevs;
+   notifier->max_subdevs = max_subdevs;
+
+   return 0;
+}
+
+static int v4l2_async_notifier_fwnode_parse_endpoint(
+   struct device *dev, struct v4l2_async_notifier *notifier,
+   struct fwnode_handle *endpoint, unsigned int asd_struct_size,
+   int (*parse_endpoint)(struct device *dev,
+   struct v4l2_fwnode_endpoint *vep,
+   struct v4l2_async_subdev *asd))
+{
+   struct v4l2_async_subdev *asd;
+   struct v4l2_fwnode_endpoint *vep;
+   int ret = 0;
+
+   asd = kzalloc(asd_struct_size, GFP_KERNEL);
+   if (!asd)
+   return -ENOMEM;
+
+   asd->match.fwnode.fwnode =
+   fwnode_graph_get_remote_port_parent(endpoint);
+   if (!asd->match.fwnode.fwnode) {
+   dev_warn(dev, "bad remote port parent\n");
+   ret = -EINVAL;
+   goto out_err;
+   }
+
+   /* Ignore endpoints the parsing of which failed. */
+   vep = v4l2_fwnode_endpoint_alloc_parse(endpoint);
+   if (IS_ERR(vep)) {
+   ret = PTR_ERR(vep);
+   dev_warn(dev, "unable to parse V4L2 fwnode endpoint (%d)\n",
+ret);
+   goto out_err;
+   }
+
+   ret = parse_endpoint ? parse_endpoint(dev, vep, asd) : 0;
+   if (ret == -ENOTCONN)
+   dev_dbg(dev, "ignoring endpoint %u,%u\n", vep->base.port,
+   vep->base.id);
+   else if (ret < 0)
+   dev_warn(dev, "driver could not parse endpoint %u,%u (%d)\n",
+vep->base.port, vep->base.id, ret);
+   v4l2_fwnode_endpoint_free(vep);
+   if (ret < 0)
+   goto out_err;
+
+   asd

[PATCH v12 09/26] omap3isp: Fix check for our own sub-devices

2017-09-12 Thread Sakari Ailus
We only want to link sub-devices that were bound to the async notifier the
isp driver registered but there may be other sub-devices in the
v4l2_device as well. Check for the correct async notifier.

Signed-off-by: Sakari Ailus 
Acked-by: Hans Verkuil 
Acked-by: Pavel Machek 
---
 drivers/media/platform/omap3isp/isp.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/media/platform/omap3isp/isp.c 
b/drivers/media/platform/omap3isp/isp.c
index a546cf774d40..3b1a9cd0e591 100644
--- a/drivers/media/platform/omap3isp/isp.c
+++ b/drivers/media/platform/omap3isp/isp.c
@@ -2155,7 +2155,7 @@ static int isp_subdev_notifier_complete(struct 
v4l2_async_notifier *async)
return ret;
 
list_for_each_entry(sd, &v4l2_dev->subdevs, list) {
-   if (!sd->asd)
+   if (sd->notifier != &isp->notifier)
continue;
 
ret = isp_link_entity(isp, &sd->entity,
-- 
2.11.0



[PATCH v12 10/26] omap3isp: Print the name of the entity where no source pads could be found

2017-09-12 Thread Sakari Ailus
If no source pads are found in an entity, print the name of the entity.

Signed-off-by: Sakari Ailus 
Acked-by: Hans Verkuil 
Acked-by: Pavel Machek 
---
 drivers/media/platform/omap3isp/isp.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/media/platform/omap3isp/isp.c 
b/drivers/media/platform/omap3isp/isp.c
index 3b1a9cd0e591..9a694924e46e 100644
--- a/drivers/media/platform/omap3isp/isp.c
+++ b/drivers/media/platform/omap3isp/isp.c
@@ -1669,8 +1669,8 @@ static int isp_link_entity(
break;
}
if (i == entity->num_pads) {
-   dev_err(isp->dev, "%s: no source pad in external entity\n",
-   __func__);
+   dev_err(isp->dev, "%s: no source pad in external entity %s\n",
+   __func__, entity->name);
return -EINVAL;
}
 
-- 
2.11.0



[PATCH v12 12/26] v4l: async: Introduce helpers for calling async ops callbacks

2017-09-12 Thread Sakari Ailus
Add three helper functions to call async operations callbacks. Besides
simplifying callbacks, this allows async notifiers to have no ops set,
i.e. it can be left NULL.

Signed-off-by: Sakari Ailus 
Acked-by: Hans Verkuil 
---
 drivers/media/v4l2-core/v4l2-async.c | 49 ++--
 include/media/v4l2-async.h   |  1 +
 2 files changed, 37 insertions(+), 13 deletions(-)

diff --git a/drivers/media/v4l2-core/v4l2-async.c 
b/drivers/media/v4l2-core/v4l2-async.c
index a2df85ea00f4..c34f93593b41 100644
--- a/drivers/media/v4l2-core/v4l2-async.c
+++ b/drivers/media/v4l2-core/v4l2-async.c
@@ -25,6 +25,34 @@
 #include 
 #include 
 
+static int v4l2_async_notifier_call_bound(struct v4l2_async_notifier *n,
+ struct v4l2_subdev *subdev,
+ struct v4l2_async_subdev *asd)
+{
+   if (!n->ops || !n->ops->bound)
+   return 0;
+
+   return n->ops->bound(n, subdev, asd);
+}
+
+static void v4l2_async_notifier_call_unbind(struct v4l2_async_notifier *n,
+   struct v4l2_subdev *subdev,
+   struct v4l2_async_subdev *asd)
+{
+   if (!n->ops || !n->ops->unbind)
+   return;
+
+   n->ops->unbind(n, subdev, asd);
+}
+
+static int v4l2_async_notifier_call_complete(struct v4l2_async_notifier *n)
+{
+   if (!n->ops || !n->ops->complete)
+   return 0;
+
+   return n->ops->complete(n);
+}
+
 static bool match_i2c(struct v4l2_subdev *sd, struct v4l2_async_subdev *asd)
 {
 #if IS_ENABLED(CONFIG_I2C)
@@ -102,16 +130,13 @@ static int v4l2_async_match_notify(struct 
v4l2_async_notifier *notifier,
 {
int ret;
 
-   if (notifier->ops->bound) {
-   ret = notifier->ops->bound(notifier, sd, asd);
-   if (ret < 0)
-   return ret;
-   }
+   ret = v4l2_async_notifier_call_bound(notifier, sd, asd);
+   if (ret < 0)
+   return ret;
 
ret = v4l2_device_register_subdev(notifier->v4l2_dev, sd);
if (ret < 0) {
-   if (notifier->ops->unbind)
-   notifier->ops->unbind(notifier, sd, asd);
+   v4l2_async_notifier_call_unbind(notifier, sd, asd);
return ret;
}
 
@@ -123,8 +148,8 @@ static int v4l2_async_match_notify(struct 
v4l2_async_notifier *notifier,
/* Move from the global subdevice list to notifier's done */
list_move(&sd->async_list, ¬ifier->done);
 
-   if (list_empty(¬ifier->waiting) && notifier->ops->complete)
-   return notifier->ops->complete(notifier);
+   if (list_empty(¬ifier->waiting))
+   return v4l2_async_notifier_call_complete(notifier);
 
return 0;
 }
@@ -210,8 +235,7 @@ void v4l2_async_notifier_unregister(struct 
v4l2_async_notifier *notifier)
list_for_each_entry_safe(sd, tmp, ¬ifier->done, async_list) {
v4l2_async_cleanup(sd);
 
-   if (notifier->ops->unbind)
-   notifier->ops->unbind(notifier, sd, sd->asd);
+   v4l2_async_notifier_call_unbind(notifier, sd, sd->asd);
}
 
mutex_unlock(&list_lock);
@@ -300,8 +324,7 @@ void v4l2_async_unregister_subdev(struct v4l2_subdev *sd)
 
v4l2_async_cleanup(sd);
 
-   if (notifier->ops->unbind)
-   notifier->ops->unbind(notifier, sd, sd->asd);
+   v4l2_async_notifier_call_unbind(notifier, sd, sd->asd);
 
mutex_unlock(&list_lock);
 }
diff --git a/include/media/v4l2-async.h b/include/media/v4l2-async.h
index 3c48f8b66d12..3bc8a7c0d83f 100644
--- a/include/media/v4l2-async.h
+++ b/include/media/v4l2-async.h
@@ -164,4 +164,5 @@ int v4l2_async_register_subdev(struct v4l2_subdev *sd);
  * @sd: pointer to &struct v4l2_subdev
  */
 void v4l2_async_unregister_subdev(struct v4l2_subdev *sd);
+
 #endif
-- 
2.11.0



[PATCH v12 11/26] v4l: async: Move async subdev notifier operations to a separate structure

2017-09-12 Thread Sakari Ailus
From: Laurent Pinchart 

The async subdev notifier .bound(), .unbind() and .complete() operations
are function pointers stored directly in the v4l2_async_subdev
structure. As the structure isn't immutable, this creates a potential
security risk as the function pointers are mutable.

To fix this, move the function pointers to a new
v4l2_async_subdev_operations structure that can be made const in
drivers.

Signed-off-by: Laurent Pinchart 
Acked-by: Hans Verkuil 
---
 drivers/media/platform/am437x/am437x-vpfe.c|  8 +--
 drivers/media/platform/atmel/atmel-isc.c   | 10 ++---
 drivers/media/platform/atmel/atmel-isi.c   | 10 ++---
 drivers/media/platform/davinci/vpif_capture.c  |  8 +--
 drivers/media/platform/davinci/vpif_display.c  |  8 +--
 drivers/media/platform/exynos4-is/media-dev.c  |  8 +--
 drivers/media/platform/omap3isp/isp.c  |  6 +-
 drivers/media/platform/pxa_camera.c|  8 +--
 drivers/media/platform/qcom/camss-8x16/camss.c |  8 +--
 drivers/media/platform/rcar-vin/rcar-core.c| 10 ++---
 drivers/media/platform/rcar_drif.c | 10 ++---
 drivers/media/platform/soc_camera/soc_camera.c | 14 +++--
 drivers/media/platform/stm32/stm32-dcmi.c  | 10 ++---
 drivers/media/platform/ti-vpe/cal.c|  8 +--
 drivers/media/platform/xilinx/xilinx-vipp.c|  8 +--
 drivers/media/v4l2-core/v4l2-async.c   | 20 +-
 drivers/staging/media/imx/imx-media-dev.c  |  8 +--
 include/media/v4l2-async.h | 29 +-
 18 files changed, 131 insertions(+), 60 deletions(-)

diff --git a/drivers/media/platform/am437x/am437x-vpfe.c 
b/drivers/media/platform/am437x/am437x-vpfe.c
index dfcc484cab89..0997c640191d 100644
--- a/drivers/media/platform/am437x/am437x-vpfe.c
+++ b/drivers/media/platform/am437x/am437x-vpfe.c
@@ -2417,6 +2417,11 @@ static int vpfe_async_complete(struct 
v4l2_async_notifier *notifier)
return vpfe_probe_complete(vpfe);
 }
 
+static const struct v4l2_async_notifier_operations vpfe_async_ops = {
+   .bound = vpfe_async_bound,
+   .complete = vpfe_async_complete,
+};
+
 static struct vpfe_config *
 vpfe_get_pdata(struct platform_device *pdev)
 {
@@ -2590,8 +2595,7 @@ static int vpfe_probe(struct platform_device *pdev)
 
vpfe->notifier.subdevs = vpfe->cfg->asd;
vpfe->notifier.num_subdevs = ARRAY_SIZE(vpfe->cfg->asd);
-   vpfe->notifier.bound = vpfe_async_bound;
-   vpfe->notifier.complete = vpfe_async_complete;
+   vpfe->notifier.ops = &vpfe_async_ops;
ret = v4l2_async_notifier_register(&vpfe->v4l2_dev,
&vpfe->notifier);
if (ret) {
diff --git a/drivers/media/platform/atmel/atmel-isc.c 
b/drivers/media/platform/atmel/atmel-isc.c
index d7103c5f92c3..48544c4137cb 100644
--- a/drivers/media/platform/atmel/atmel-isc.c
+++ b/drivers/media/platform/atmel/atmel-isc.c
@@ -1639,6 +1639,12 @@ static int isc_async_complete(struct v4l2_async_notifier 
*notifier)
return 0;
 }
 
+static const struct v4l2_async_notifier_operations isc_async_ops = {
+   .bound = isc_async_bound,
+   .unbind = isc_async_unbind,
+   .complete = isc_async_complete,
+};
+
 static void isc_subdev_cleanup(struct isc_device *isc)
 {
struct isc_subdev_entity *subdev_entity;
@@ -1851,9 +1857,7 @@ static int atmel_isc_probe(struct platform_device *pdev)
list_for_each_entry(subdev_entity, &isc->subdev_entities, list) {
subdev_entity->notifier.subdevs = &subdev_entity->asd;
subdev_entity->notifier.num_subdevs = 1;
-   subdev_entity->notifier.bound = isc_async_bound;
-   subdev_entity->notifier.unbind = isc_async_unbind;
-   subdev_entity->notifier.complete = isc_async_complete;
+   subdev_entity->notifier.ops = &isc_async_ops;
 
ret = v4l2_async_notifier_register(&isc->v4l2_dev,
   &subdev_entity->notifier);
diff --git a/drivers/media/platform/atmel/atmel-isi.c 
b/drivers/media/platform/atmel/atmel-isi.c
index 891fa2505efa..eadbf9def358 100644
--- a/drivers/media/platform/atmel/atmel-isi.c
+++ b/drivers/media/platform/atmel/atmel-isi.c
@@ -1105,6 +1105,12 @@ static int isi_graph_notify_bound(struct 
v4l2_async_notifier *notifier,
return 0;
 }
 
+static const struct v4l2_async_notifier_operations isi_graph_notify_ops = {
+   .bound = isi_graph_notify_bound,
+   .unbind = isi_graph_notify_unbind,
+   .complete = isi_graph_notify_complete,
+};
+
 static int isi_graph_parse(struct atmel_isi *isi, struct device_node *node)
 {
struct device_node *ep = NULL;
@@ -1152,9 +1158,7 @@ static int isi_graph_init(struct atmel_isi *isi)
 
isi->notifier.subdevs = subdevs;
isi->notifier.num_subdevs = 1;
-   isi->notifier.bound = isi_graph_notify_bound;
-  

[PATCH v12 02/26] v4l: async: Remove re-probing support

2017-09-12 Thread Sakari Ailus
Remove V4L2 async re-probing support. The re-probing support has been
there to support cases where the sub-devices require resources provided by
the main driver's hardware to function, such as clocks.

Reprobing has allowed unbinding and again binding the main driver without
explicilty unbinding the sub-device drivers. This is certainly not a
common need, and the responsibility will be the user's going forward.

An alternative could have been to introduce notifier specific locks.
Considering the complexity of the re-probing and that it isn't really a
solution to a problem but a workaround, remove re-probing instead.

Signed-off-by: Sakari Ailus 
Acked-by: Hans Verkuil 
---
 drivers/media/v4l2-core/v4l2-async.c | 54 
 1 file changed, 54 deletions(-)

diff --git a/drivers/media/v4l2-core/v4l2-async.c 
b/drivers/media/v4l2-core/v4l2-async.c
index d741a8e0fdac..e109d9da4653 100644
--- a/drivers/media/v4l2-core/v4l2-async.c
+++ b/drivers/media/v4l2-core/v4l2-async.c
@@ -198,78 +198,24 @@ EXPORT_SYMBOL(v4l2_async_notifier_register);
 void v4l2_async_notifier_unregister(struct v4l2_async_notifier *notifier)
 {
struct v4l2_subdev *sd, *tmp;
-   unsigned int notif_n_subdev = notifier->num_subdevs;
-   unsigned int n_subdev = min(notif_n_subdev, V4L2_MAX_SUBDEVS);
-   struct device **dev;
-   int i = 0;
 
if (!notifier->v4l2_dev)
return;
 
-   dev = kvmalloc_array(n_subdev, sizeof(*dev), GFP_KERNEL);
-   if (!dev) {
-   dev_err(notifier->v4l2_dev->dev,
-   "Failed to allocate device cache!\n");
-   }
-
mutex_lock(&list_lock);
 
list_del(¬ifier->list);
 
list_for_each_entry_safe(sd, tmp, ¬ifier->done, async_list) {
-   struct device *d;
-
-   d = get_device(sd->dev);
-
v4l2_async_cleanup(sd);
 
-   /* If we handled USB devices, we'd have to lock the parent too 
*/
-   device_release_driver(d);
-
if (notifier->unbind)
notifier->unbind(notifier, sd, sd->asd);
-
-   /*
-* Store device at the device cache, in order to call
-* put_device() on the final step
-*/
-   if (dev)
-   dev[i++] = d;
-   else
-   put_device(d);
}
 
mutex_unlock(&list_lock);
 
-   /*
-* Call device_attach() to reprobe devices
-*
-* NOTE: If dev allocation fails, i is 0, and the whole loop won't be
-* executed.
-*/
-   while (i--) {
-   struct device *d = dev[i];
-
-   if (d && device_attach(d) < 0) {
-   const char *name = "(none)";
-   int lock = device_trylock(d);
-
-   if (lock && d->driver)
-   name = d->driver->name;
-   dev_err(d, "Failed to re-probe to %s\n", name);
-   if (lock)
-   device_unlock(d);
-   }
-   put_device(d);
-   }
-   kvfree(dev);
-
notifier->v4l2_dev = NULL;
-
-   /*
-* Don't care about the waiting list, it is initialised and populated
-* upon notifier registration.
-*/
 }
 EXPORT_SYMBOL(v4l2_async_notifier_unregister);
 
-- 
2.11.0



Re: [media] s5p-mfc: Adjust a null pointer check in four functions

2017-09-12 Thread Sylwester Nawrocki

On 09/11/2017 09:21 PM, SF Markus Elfring wrote:

Date: Fri, 8 Sep 2017 22:37:00 +0200
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit


Can you resend with that 4 lines removed?


* Do you care to preserve an information like the author date?


In this case not, but actually the Date line is not an issue.  Anyway
the patch is malformed, please try to save your posted patch and apply
with git am and see how finally the commit message looks like.


* Would you like to support special characters in the commit message?


I can't see any need for special characters in the patch itself.
Please submit the patch in a way that it can be applied properly with
patchwork client (or git am).


Are you using git send-email for sending patches?


Not so far.


I would suggest switching to git send-email, then issues like
above could be easily avoided.

--
Regards,
Sylwester


Duplicated debug message in drivers/media/rc/rc-main.c

2017-09-12 Thread Mason

Hello,

I enabled all debug messages, and I see:

[1.931214] Allocated space for 1 keycode entries (8 bytes)
[1.936822] Allocated space for 1 keycode entries (8 bytes)

One comes from ir_create_table()
The other from ir_setkeytable()

ir_setkeytable() calls ir_create_table()

It looks like one of the two debug messages should be deleted?

Regards.



Re: as3645a flash userland interface

2017-09-12 Thread Sakari Ailus
Ahoy!

On Tue, Sep 12, 2017 at 01:40:51PM +0200, Pavel Machek wrote:
> Hi!
> 
> > On Tue, Sep 12, 2017 at 12:36:28PM +0200, Pavel Machek wrote:
> > > Hi!
> > > 
> > > There were some changes to as3645a flash controller. Before we have
> > > stable interface we have to keep forever I want to ask:
> > > 
> > > What directory are the flash controls in?
> > > 
> > > /sys/class/leds/led-controller:flash ?
> > > 
> > > Could we arrange for something less generic, like
> > > 
> > > /sys/class/leds/main-camera:flash ?
> > > 
> > > Thanks,
> > 
> > The LEDs are called as3645a:flash and as3645a:indicator currently, based on
> > the name of the LED controller's device node. There are no patches related
> > to this set though; these have already been merged.
> > 
> > The label should be a "human readable string describing the device" (from
> > ePAPR, please excuse me for not having a newer spec), and the led common
> > bindings define it as:
> > 
> > - label : The label for this LED. If omitted, the label is taken from the 
> > node
> >   name (excluding the unit address). It has to uniquely identify
> >   a device, i.e. no other LED class device can be assigned the same
> >   label.
> 
> Ok, can we set the label to "main_camera" for N9 and n950 cases?
> 
> "as3645a:flash" is really wrong name for a LED. Information that
> as3645 is already present elsewhere in /sys. Information where the LED
> is and what it does is not.
> 
> I'd like to have torch application that just writes
> /sys/class/leds/main_camera:white:flash/brightness . It should not
> need to know hardware details of differnet phones.

Hmm. There don't seem to be a uniform way to form labels.

What I'd do is to look up a LED that implements LED flash class and use
that; it's a flash LED and is likely to be the most powerful in the system.
There could be several as well, some more recent flash controllers have
more than one.

I wonder what Jacek thinks.

> 
> > I don't think that you should be looking to use this to associate it with
> > the camera as such. The association information with the sensor is
> > available to the kernel but there's no interface that could meaningfully
> > expose it to the user right now.
> 
> Yeah, I'm not looking for sensor association. I'm looking for
> reasonable userland interface.

Ack. Hopefully we can provide the association some day, too...

-- 
Kind regards,

Sakari Ailus
e-mail: sakari.ai...@iki.fi


Re: as3645a flash userland interface

2017-09-12 Thread Pavel Machek
Hi!

> On Tue, Sep 12, 2017 at 12:36:28PM +0200, Pavel Machek wrote:
> > Hi!
> > 
> > There were some changes to as3645a flash controller. Before we have
> > stable interface we have to keep forever I want to ask:
> > 
> > What directory are the flash controls in?
> > 
> > /sys/class/leds/led-controller:flash ?
> > 
> > Could we arrange for something less generic, like
> > 
> > /sys/class/leds/main-camera:flash ?
> > 
> > Thanks,
> 
> The LEDs are called as3645a:flash and as3645a:indicator currently, based on
> the name of the LED controller's device node. There are no patches related
> to this set though; these have already been merged.
> 
> The label should be a "human readable string describing the device" (from
> ePAPR, please excuse me for not having a newer spec), and the led common
> bindings define it as:
> 
> - label : The label for this LED. If omitted, the label is taken from the node
>   name (excluding the unit address). It has to uniquely identify
>   a device, i.e. no other LED class device can be assigned the same
>   label.

Ok, can we set the label to "main_camera" for N9 and n950 cases?

"as3645a:flash" is really wrong name for a LED. Information that
as3645 is already present elsewhere in /sys. Information where the LED
is and what it does is not.

I'd like to have torch application that just writes
/sys/class/leds/main_camera:white:flash/brightness . It should not
need to know hardware details of differnet phones.

> I don't think that you should be looking to use this to associate it with
> the camera as such. The association information with the sensor is
> available to the kernel but there's no interface that could meaningfully
> expose it to the user right now.

Yeah, I'm not looking for sensor association. I'm looking for
reasonable userland interface.

Thanks,
Pavel

-- 
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) 
http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html


signature.asc
Description: Digital signature


[PATCH] [media] gspca: make arrays static, reduces object code size

2017-09-12 Thread Colin King
From: Colin Ian King 

Don't populate const arrays on the stack, instead make them
static.  Makes the object code smaller by over 5200 bytes:

Before:
   textdata bss dec hex filename
  582598880 128   67267   106c3 ov519.o

After:
   textdata bss dec hex filename
  521559776 128   62059f26b ov519.o

Signed-off-by: Colin Ian King 
---
 drivers/media/usb/gspca/ov519.c | 22 +++---
 1 file changed, 11 insertions(+), 11 deletions(-)

diff --git a/drivers/media/usb/gspca/ov519.c b/drivers/media/usb/gspca/ov519.c
index cdb79c5f0c38..f1537daf4e2e 100644
--- a/drivers/media/usb/gspca/ov519.c
+++ b/drivers/media/usb/gspca/ov519.c
@@ -2865,7 +2865,7 @@ static void sd_reset_snapshot(struct gspca_dev *gspca_dev)
 
 static void ov51x_upload_quan_tables(struct sd *sd)
 {
-   const unsigned char yQuanTable511[] = {
+   static const unsigned char yQuanTable511[] = {
0, 1, 1, 2, 2, 3, 3, 4,
1, 1, 1, 2, 2, 3, 4, 4,
1, 1, 2, 2, 3, 4, 4, 4,
@@ -2876,7 +2876,7 @@ static void ov51x_upload_quan_tables(struct sd *sd)
4, 4, 4, 4, 5, 5, 5, 5
};
 
-   const unsigned char uvQuanTable511[] = {
+   static const unsigned char uvQuanTable511[] = {
0, 2, 2, 3, 4, 4, 4, 4,
2, 2, 2, 4, 4, 4, 4, 4,
2, 2, 3, 4, 4, 4, 4, 4,
@@ -2888,13 +2888,13 @@ static void ov51x_upload_quan_tables(struct sd *sd)
};
 
/* OV518 quantization tables are 8x4 (instead of 8x8) */
-   const unsigned char yQuanTable518[] = {
+   static const unsigned char yQuanTable518[] = {
5, 4, 5, 6, 6, 7, 7, 7,
5, 5, 5, 5, 6, 7, 7, 7,
6, 6, 6, 6, 7, 7, 7, 8,
7, 7, 6, 7, 7, 7, 8, 8
};
-   const unsigned char uvQuanTable518[] = {
+   static const unsigned char uvQuanTable518[] = {
6, 6, 6, 7, 7, 7, 7, 7,
6, 6, 6, 7, 7, 7, 7, 7,
6, 6, 6, 7, 7, 7, 7, 8,
@@ -2943,7 +2943,7 @@ static void ov511_configure(struct gspca_dev *gspca_dev)
struct sd *sd = (struct sd *) gspca_dev;
 
/* For 511 and 511+ */
-   const struct ov_regvals init_511[] = {
+   static const struct ov_regvals init_511[] = {
{ R51x_SYS_RESET,   0x7f },
{ R51x_SYS_INIT,0x01 },
{ R51x_SYS_RESET,   0x7f },
@@ -2953,7 +2953,7 @@ static void ov511_configure(struct gspca_dev *gspca_dev)
{ R51x_SYS_RESET,   0x3d },
};
 
-   const struct ov_regvals norm_511[] = {
+   static const struct ov_regvals norm_511[] = {
{ R511_DRAM_FLOW_CTL,   0x01 },
{ R51x_SYS_SNAP,0x00 },
{ R51x_SYS_SNAP,0x02 },
@@ -2963,7 +2963,7 @@ static void ov511_configure(struct gspca_dev *gspca_dev)
{ R511_COMP_LUT_EN, 0x03 },
};
 
-   const struct ov_regvals norm_511_p[] = {
+   static const struct ov_regvals norm_511_p[] = {
{ R511_DRAM_FLOW_CTL,   0xff },
{ R51x_SYS_SNAP,0x00 },
{ R51x_SYS_SNAP,0x02 },
@@ -2973,7 +2973,7 @@ static void ov511_configure(struct gspca_dev *gspca_dev)
{ R511_COMP_LUT_EN, 0x03 },
};
 
-   const struct ov_regvals compress_511[] = {
+   static const struct ov_regvals compress_511[] = {
{ 0x70, 0x1f },
{ 0x71, 0x05 },
{ 0x72, 0x06 },
@@ -3009,7 +3009,7 @@ static void ov518_configure(struct gspca_dev *gspca_dev)
struct sd *sd = (struct sd *) gspca_dev;
 
/* For 518 and 518+ */
-   const struct ov_regvals init_518[] = {
+   static const struct ov_regvals init_518[] = {
{ R51x_SYS_RESET,   0x40 },
{ R51x_SYS_INIT,0xe1 },
{ R51x_SYS_RESET,   0x3e },
@@ -3020,7 +3020,7 @@ static void ov518_configure(struct gspca_dev *gspca_dev)
{ 0x5d, 0x03 },
};
 
-   const struct ov_regvals norm_518[] = {
+   static const struct ov_regvals norm_518[] = {
{ R51x_SYS_SNAP,0x02 }, /* Reset */
{ R51x_SYS_SNAP,0x01 }, /* Enable */
{ 0x31, 0x0f },
@@ -3033,7 +3033,7 @@ static void ov518_configure(struct gspca_dev *gspca_dev)
{ 0x2f, 0x80 },
};
 
-   const struct ov_regvals norm_518_p[] = {
+   static const struct ov_regvals norm_518_p[] = {
{ R51x_SYS_SNAP,0x02 }, /* Reset */
{ R51x_SYS_SNAP,0x01 }, /* Enable */
{ 0x31, 0x0f },
-- 
2.14.1



Re: [PATCH] et8ek8: Add support for flash and lens devices

2017-09-12 Thread Sakari Ailus
Hi Pavel,

On Mon, Sep 11, 2017 at 03:18:31PM +0200, Pavel Machek wrote:
> Parse async sub-devices by using
> v4l2_subdev_fwnode_reference_parse_sensor_common().
> 
> These types devices aren't directly related to the sensor, but are
> nevertheless handled by the et8ek8 driver due to the relationship of these
> component to the main part of the camera module --- the sensor.
> 
> Signed-off-by: Pavel Machek 
> 
> ---
> 
> This enables me to do autofocus on n900.
> 
> Depends on Sakari's series, so best solution would be to append it there.

I added this after the smiapp driver changes.

-- 
Sakari Ailus
e-mail: sakari.ai...@iki.fi


Re: as3645a flash userland interface

2017-09-12 Thread Sakari Ailus
Hi Pavel,

On Tue, Sep 12, 2017 at 12:36:28PM +0200, Pavel Machek wrote:
> Hi!
> 
> There were some changes to as3645a flash controller. Before we have
> stable interface we have to keep forever I want to ask:
> 
> What directory are the flash controls in?
> 
> /sys/class/leds/led-controller:flash ?
> 
> Could we arrange for something less generic, like
> 
> /sys/class/leds/main-camera:flash ?
> 
> Thanks,

The LEDs are called as3645a:flash and as3645a:indicator currently, based on
the name of the LED controller's device node. There are no patches related
to this set though; these have already been merged.

The label should be a "human readable string describing the device" (from
ePAPR, please excuse me for not having a newer spec), and the led common
bindings define it as:

- label : The label for this LED. If omitted, the label is taken from the node
  name (excluding the unit address). It has to uniquely identify
  a device, i.e. no other LED class device can be assigned the same
  label.

I don't think that you should be looking to use this to associate it with
the camera as such. The association information with the sensor is
available to the kernel but there's no interface that could meaningfully
expose it to the user right now.

-- 
Regards,

Sakari Ailus
e-mail: sakari.ai...@iki.fi


as3645a flash userland interface

2017-09-12 Thread Pavel Machek
Hi!

There were some changes to as3645a flash controller. Before we have
stable interface we have to keep forever I want to ask:

What directory are the flash controls in?

/sys/class/leds/led-controller:flash ?

Could we arrange for something less generic, like

/sys/class/leds/main-camera:flash ?

Thanks,

Pavel
 
-- 
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) 
http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html


signature.asc
Description: Digital signature


Re: [PATCH v11 21/24] smiapp: Add support for flash and lens devices

2017-09-12 Thread Pavel Machek
On Tue 2017-09-12 11:42:33, Sakari Ailus wrote:
> Parse async sub-devices by using
> v4l2_subdev_fwnode_reference_parse_sensor_common().
> 
> These types devices aren't directly related to the sensor, but are
> nevertheless handled by the smiapp driver due to the relationship of these
> component to the main part of the camera module --- the sensor.
> 
> This does not yet address providing the user space with information on how
> to associate the sensor or lens devices but the kernel now has the
> necessary information to do that.
> 
> Signed-off-by: Sakari Ailus 
> Acked-by: Hans Verkuil 

Acked-by: Pavel Machek 


-- 
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) 
http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html


signature.asc
Description: Digital signature


[PATCH] media: dvb_frontend: only use kref after initialized

2017-09-12 Thread Mauro Carvalho Chehab

As reported by Laurent, when a DVB frontend need to register
two drivers (e. g. a tuner and a demod), if the second driver
fails to register (for example because it was not compiled),
the error handling logic frees the frontend by calling
dvb_frontend_detach(). That used to work fine, but changeset
1f862a68df24 ("[media] dvb_frontend: move kref to struct dvb_frontend")
added a kref at struct dvb_frontend. So, now, instead of just
freeing the data, the error handling do a kref_put().

That works fine only after dvb_register_frontend() succeeds.

While it would be possible to add a helper function that
would be initializing earlier the kref, that would require
changing every single DVB frontend on non-trivial ways, and
would make frontends different than other drivers.

So, instead of doing that, let's focus on the real issue:
only call kref_put() after kref_init(). That's easy to
check, as, when the dvb frontend is successfuly registered,
it will allocate its own private struct. So, if such
struct is allocated, it means that it is safe to use
kref_put(). If not, then nobody is using yet the frontend,
and it is safe to just deallocate it.

Fixes: 1f862a68df24 ("[media] dvb_frontend: move kref to struct dvb_frontend")
Reported-by: Laurent Pinchart 
Signed-off-by: Mauro Carvalho Chehab 
---

Laurent,

Could you please check if this patch fixes the issue you noticed?

Thanks!

 drivers/media/dvb-core/dvb_frontend.c | 25 +
 1 file changed, 21 insertions(+), 4 deletions(-)

diff --git a/drivers/media/dvb-core/dvb_frontend.c 
b/drivers/media/dvb-core/dvb_frontend.c
index 2fcba1616168..9139d01ba7ed 100644
--- a/drivers/media/dvb-core/dvb_frontend.c
+++ b/drivers/media/dvb-core/dvb_frontend.c
@@ -141,22 +141,39 @@ struct dvb_frontend_private {
 static void dvb_frontend_invoke_release(struct dvb_frontend *fe,
void (*release)(struct dvb_frontend 
*fe));
 
-static void dvb_frontend_free(struct kref *ref)
+static void __dvb_frontend_free(struct dvb_frontend *fe)
 {
-   struct dvb_frontend *fe =
-   container_of(ref, struct dvb_frontend, refcount);
struct dvb_frontend_private *fepriv = fe->frontend_priv;
 
+   if (!fepriv)
+   return;
+
dvb_free_device(fepriv->dvbdev);
 
dvb_frontend_invoke_release(fe, fe->ops.release);
 
kfree(fepriv);
+   fe->frontend_priv = NULL;
+}
+
+static void dvb_frontend_free(struct kref *ref)
+{
+   struct dvb_frontend *fe =
+   container_of(ref, struct dvb_frontend, refcount);
+
+   __dvb_frontend_free(fe);
 }
 
 static void dvb_frontend_put(struct dvb_frontend *fe)
 {
-   kref_put(&fe->refcount, dvb_frontend_free);
+   /*
+* Check if the frontend was registered, as otherwise
+* kref was not initialized yet.
+*/
+   if (fe->frontend_priv)
+   kref_put(&fe->refcount, dvb_frontend_free);
+   else
+   __dvb_frontend_free(fe);
 }
 
 static void dvb_frontend_get(struct dvb_frontend *fe)
-- 
2.13.5




Re: [PATCH v11 11/24] v4l: async: Introduce helpers for calling async ops callbacks

2017-09-12 Thread Hans Verkuil
On 09/12/17 10:42, Sakari Ailus wrote:
> Add three helper functions to call async operations callbacks. Besides
> simplifying callbacks, this allows async notifiers to have no ops set,
> i.e. it can be left NULL.
> 
> Signed-off-by: Sakari Ailus 

I'm sure I acked this already, but in case it was lost:

Acked-by: Hans Verkuil 

Regards,

Hans

> ---
>  drivers/media/v4l2-core/v4l2-async.c | 49 
> ++--
>  include/media/v4l2-async.h   |  1 +
>  2 files changed, 37 insertions(+), 13 deletions(-)
> 
> diff --git a/drivers/media/v4l2-core/v4l2-async.c 
> b/drivers/media/v4l2-core/v4l2-async.c
> index a2df85ea00f4..c34f93593b41 100644
> --- a/drivers/media/v4l2-core/v4l2-async.c
> +++ b/drivers/media/v4l2-core/v4l2-async.c
> @@ -25,6 +25,34 @@
>  #include 
>  #include 
>  
> +static int v4l2_async_notifier_call_bound(struct v4l2_async_notifier *n,
> +   struct v4l2_subdev *subdev,
> +   struct v4l2_async_subdev *asd)
> +{
> + if (!n->ops || !n->ops->bound)
> + return 0;
> +
> + return n->ops->bound(n, subdev, asd);
> +}
> +
> +static void v4l2_async_notifier_call_unbind(struct v4l2_async_notifier *n,
> + struct v4l2_subdev *subdev,
> + struct v4l2_async_subdev *asd)
> +{
> + if (!n->ops || !n->ops->unbind)
> + return;
> +
> + n->ops->unbind(n, subdev, asd);
> +}
> +
> +static int v4l2_async_notifier_call_complete(struct v4l2_async_notifier *n)
> +{
> + if (!n->ops || !n->ops->complete)
> + return 0;
> +
> + return n->ops->complete(n);
> +}
> +
>  static bool match_i2c(struct v4l2_subdev *sd, struct v4l2_async_subdev *asd)
>  {
>  #if IS_ENABLED(CONFIG_I2C)
> @@ -102,16 +130,13 @@ static int v4l2_async_match_notify(struct 
> v4l2_async_notifier *notifier,
>  {
>   int ret;
>  
> - if (notifier->ops->bound) {
> - ret = notifier->ops->bound(notifier, sd, asd);
> - if (ret < 0)
> - return ret;
> - }
> + ret = v4l2_async_notifier_call_bound(notifier, sd, asd);
> + if (ret < 0)
> + return ret;
>  
>   ret = v4l2_device_register_subdev(notifier->v4l2_dev, sd);
>   if (ret < 0) {
> - if (notifier->ops->unbind)
> - notifier->ops->unbind(notifier, sd, asd);
> + v4l2_async_notifier_call_unbind(notifier, sd, asd);
>   return ret;
>   }
>  
> @@ -123,8 +148,8 @@ static int v4l2_async_match_notify(struct 
> v4l2_async_notifier *notifier,
>   /* Move from the global subdevice list to notifier's done */
>   list_move(&sd->async_list, ¬ifier->done);
>  
> - if (list_empty(¬ifier->waiting) && notifier->ops->complete)
> - return notifier->ops->complete(notifier);
> + if (list_empty(¬ifier->waiting))
> + return v4l2_async_notifier_call_complete(notifier);
>  
>   return 0;
>  }
> @@ -210,8 +235,7 @@ void v4l2_async_notifier_unregister(struct 
> v4l2_async_notifier *notifier)
>   list_for_each_entry_safe(sd, tmp, ¬ifier->done, async_list) {
>   v4l2_async_cleanup(sd);
>  
> - if (notifier->ops->unbind)
> - notifier->ops->unbind(notifier, sd, sd->asd);
> + v4l2_async_notifier_call_unbind(notifier, sd, sd->asd);
>   }
>  
>   mutex_unlock(&list_lock);
> @@ -300,8 +324,7 @@ void v4l2_async_unregister_subdev(struct v4l2_subdev *sd)
>  
>   v4l2_async_cleanup(sd);
>  
> - if (notifier->ops->unbind)
> - notifier->ops->unbind(notifier, sd, sd->asd);
> + v4l2_async_notifier_call_unbind(notifier, sd, sd->asd);
>  
>   mutex_unlock(&list_lock);
>  }
> diff --git a/include/media/v4l2-async.h b/include/media/v4l2-async.h
> index 3c48f8b66d12..3bc8a7c0d83f 100644
> --- a/include/media/v4l2-async.h
> +++ b/include/media/v4l2-async.h
> @@ -164,4 +164,5 @@ int v4l2_async_register_subdev(struct v4l2_subdev *sd);
>   * @sd: pointer to &struct v4l2_subdev
>   */
>  void v4l2_async_unregister_subdev(struct v4l2_subdev *sd);
> +
>  #endif
> 



Re: [PATCH v11 13/24] v4l: async: Allow async notifier register call succeed with no subdevs

2017-09-12 Thread Hans Verkuil
On 09/12/17 10:42, Sakari Ailus wrote:
> The information on how many async sub-devices would be bindable to a
> notifier is typically dependent on information from platform firmware and
> it's not driver's business to be aware of that.
> 
> Many V4L2 main drivers are perfectly usable (and useful) without async
> sub-devices and so if there aren't any around, just proceed call the
> notifier's complete callback immediately without registering the notifier
> itself.
> 
> If a driver needs to check whether there are async sub-devices available,
> it can be done by inspecting the notifier's num_subdevs field which tells
> the number of async sub-devices.
> 
> Signed-off-by: Sakari Ailus 

Acked-by: Hans Verkuil 

Regards,

Hans

> ---
>  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 7b396ff4302b..4525b03d59c1 100644
> --- a/drivers/media/v4l2-core/v4l2-async.c
> +++ b/drivers/media/v4l2-core/v4l2-async.c
> @@ -170,14 +170,16 @@ int v4l2_async_notifier_register(struct v4l2_device 
> *v4l2_dev,
>   struct v4l2_async_subdev *asd;
>   int i;
>  
> - if (!v4l2_dev || !notifier->num_subdevs ||
> - notifier->num_subdevs > V4L2_MAX_SUBDEVS)
> + if (!v4l2_dev || notifier->num_subdevs > V4L2_MAX_SUBDEVS)
>   return -EINVAL;
>  
>   notifier->v4l2_dev = v4l2_dev;
>   INIT_LIST_HEAD(¬ifier->waiting);
>   INIT_LIST_HEAD(¬ifier->done);
>  
> + if (!notifier->num_subdevs)
> + return v4l2_async_notifier_call_complete(notifier);
> +
>   for (i = 0; i < notifier->num_subdevs; i++) {
>   asd = notifier->subdevs[i];
>  
> 



[PATCH] [media] ov2640: make array reset_seq static, reduces object code size

2017-09-12 Thread Colin King
From: Colin Ian King 

Don't populate the array reset_seq on the stack, instead make it
static.  Makes the object code smaller by over 50 bytes:

Before:
   textdata bss dec hex filename
  117376000  64   178014589 drivers/media/i2c/ov2640.o

After:
   textdata bss dec hex filename
  115826096  64   17742454e drivers/media/i2c/ov2640.o

Signed-off-by: Colin Ian King 
---
 drivers/media/i2c/ov2640.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/media/i2c/ov2640.c b/drivers/media/i2c/ov2640.c
index e6d0c1f64f0b..c290fbdc2336 100644
--- a/drivers/media/i2c/ov2640.c
+++ b/drivers/media/i2c/ov2640.c
@@ -685,7 +685,7 @@ static int ov2640_mask_set(struct i2c_client *client,
 static int ov2640_reset(struct i2c_client *client)
 {
int ret;
-   const struct regval_list reset_seq[] = {
+   static const struct regval_list reset_seq[] = {
{BANK_SEL, BANK_SEL_SENS},
{COM7, COM7_SRST},
ENDMARKER,
-- 
2.14.1



[PATCH v11 03/24] v4l: async: Use more intuitive names for internal functions

2017-09-12 Thread Sakari Ailus
Rename internal functions to make the names of the functions better
describe what they do.

Old nameNew name
v4l2_async_test_notify  v4l2_async_match_notify
v4l2_async_belongs  v4l2_async_find_match

Signed-off-by: Sakari Ailus 
Acked-by: Hans Verkuil 
Acked-by: Pavel Machek 
Reviewed-by: Laurent Pinchart 
---
 drivers/media/v4l2-core/v4l2-async.c | 19 ++-
 1 file changed, 10 insertions(+), 9 deletions(-)

diff --git a/drivers/media/v4l2-core/v4l2-async.c 
b/drivers/media/v4l2-core/v4l2-async.c
index e109d9da4653..831f185ecd47 100644
--- a/drivers/media/v4l2-core/v4l2-async.c
+++ b/drivers/media/v4l2-core/v4l2-async.c
@@ -60,8 +60,8 @@ static LIST_HEAD(subdev_list);
 static LIST_HEAD(notifier_list);
 static DEFINE_MUTEX(list_lock);
 
-static struct v4l2_async_subdev *v4l2_async_belongs(struct v4l2_async_notifier 
*notifier,
-   struct v4l2_subdev *sd)
+static struct v4l2_async_subdev *v4l2_async_find_match(
+   struct v4l2_async_notifier *notifier, struct v4l2_subdev *sd)
 {
bool (*match)(struct v4l2_subdev *, struct v4l2_async_subdev *);
struct v4l2_async_subdev *asd;
@@ -95,9 +95,9 @@ static struct v4l2_async_subdev *v4l2_async_belongs(struct 
v4l2_async_notifier *
return NULL;
 }
 
-static int v4l2_async_test_notify(struct v4l2_async_notifier *notifier,
- struct v4l2_subdev *sd,
- struct v4l2_async_subdev *asd)
+static int v4l2_async_match_notify(struct v4l2_async_notifier *notifier,
+  struct v4l2_subdev *sd,
+  struct v4l2_async_subdev *asd)
 {
int ret;
 
@@ -175,11 +175,11 @@ int v4l2_async_notifier_register(struct v4l2_device 
*v4l2_dev,
list_for_each_entry_safe(sd, tmp, &subdev_list, async_list) {
int ret;
 
-   asd = v4l2_async_belongs(notifier, sd);
+   asd = v4l2_async_find_match(notifier, sd);
if (!asd)
continue;
 
-   ret = v4l2_async_test_notify(notifier, sd, asd);
+   ret = v4l2_async_match_notify(notifier, sd, asd);
if (ret < 0) {
mutex_unlock(&list_lock);
return ret;
@@ -236,9 +236,10 @@ int v4l2_async_register_subdev(struct v4l2_subdev *sd)
INIT_LIST_HEAD(&sd->async_list);
 
list_for_each_entry(notifier, ¬ifier_list, list) {
-   struct v4l2_async_subdev *asd = v4l2_async_belongs(notifier, 
sd);
+   struct v4l2_async_subdev *asd = v4l2_async_find_match(notifier,
+ sd);
if (asd) {
-   int ret = v4l2_async_test_notify(notifier, sd, asd);
+   int ret = v4l2_async_match_notify(notifier, sd, asd);
mutex_unlock(&list_lock);
return ret;
}
-- 
2.11.0



[PATCH v11 20/24] dt: bindings: smiapp: Document lens-focus and flash-leds properties

2017-09-12 Thread Sakari Ailus
Document optional lens-focus and flash-leds properties for the smiapp driver.

Signed-off-by: Sakari Ailus 
Acked-by: Hans Verkuil 
Acked-by: Pavel Machek 
---
 Documentation/devicetree/bindings/media/i2c/nokia,smia.txt | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/Documentation/devicetree/bindings/media/i2c/nokia,smia.txt 
b/Documentation/devicetree/bindings/media/i2c/nokia,smia.txt
index 855e1faf73e2..33f10a94c381 100644
--- a/Documentation/devicetree/bindings/media/i2c/nokia,smia.txt
+++ b/Documentation/devicetree/bindings/media/i2c/nokia,smia.txt
@@ -27,6 +27,8 @@ Optional properties
 - nokia,nvm-size: The size of the NVM, in bytes. If the size is not given,
   the NVM contents will not be read.
 - reset-gpios: XSHUTDOWN GPIO
+- flash-leds: See ../video-interfaces.txt
+- lens-focus: See ../video-interfaces.txt
 
 
 Endpoint node mandatory properties
-- 
2.11.0



[PATCH v11 02/24] v4l: async: Remove re-probing support

2017-09-12 Thread Sakari Ailus
Remove V4L2 async re-probing support. The re-probing support has been
there to support cases where the sub-devices require resources provided by
the main driver's hardware to function, such as clocks.

Reprobing has allowed unbinding and again binding the main driver without
explicilty unbinding the sub-device drivers. This is certainly not a
common need, and the responsibility will be the user's going forward.

An alternative could have been to introduce notifier specific locks.
Considering the complexity of the re-probing and that it isn't really a
solution to a problem but a workaround, remove re-probing instead.

Signed-off-by: Sakari Ailus 
Acked-by: Hans Verkuil 
---
 drivers/media/v4l2-core/v4l2-async.c | 54 
 1 file changed, 54 deletions(-)

diff --git a/drivers/media/v4l2-core/v4l2-async.c 
b/drivers/media/v4l2-core/v4l2-async.c
index d741a8e0fdac..e109d9da4653 100644
--- a/drivers/media/v4l2-core/v4l2-async.c
+++ b/drivers/media/v4l2-core/v4l2-async.c
@@ -198,78 +198,24 @@ EXPORT_SYMBOL(v4l2_async_notifier_register);
 void v4l2_async_notifier_unregister(struct v4l2_async_notifier *notifier)
 {
struct v4l2_subdev *sd, *tmp;
-   unsigned int notif_n_subdev = notifier->num_subdevs;
-   unsigned int n_subdev = min(notif_n_subdev, V4L2_MAX_SUBDEVS);
-   struct device **dev;
-   int i = 0;
 
if (!notifier->v4l2_dev)
return;
 
-   dev = kvmalloc_array(n_subdev, sizeof(*dev), GFP_KERNEL);
-   if (!dev) {
-   dev_err(notifier->v4l2_dev->dev,
-   "Failed to allocate device cache!\n");
-   }
-
mutex_lock(&list_lock);
 
list_del(¬ifier->list);
 
list_for_each_entry_safe(sd, tmp, ¬ifier->done, async_list) {
-   struct device *d;
-
-   d = get_device(sd->dev);
-
v4l2_async_cleanup(sd);
 
-   /* If we handled USB devices, we'd have to lock the parent too 
*/
-   device_release_driver(d);
-
if (notifier->unbind)
notifier->unbind(notifier, sd, sd->asd);
-
-   /*
-* Store device at the device cache, in order to call
-* put_device() on the final step
-*/
-   if (dev)
-   dev[i++] = d;
-   else
-   put_device(d);
}
 
mutex_unlock(&list_lock);
 
-   /*
-* Call device_attach() to reprobe devices
-*
-* NOTE: If dev allocation fails, i is 0, and the whole loop won't be
-* executed.
-*/
-   while (i--) {
-   struct device *d = dev[i];
-
-   if (d && device_attach(d) < 0) {
-   const char *name = "(none)";
-   int lock = device_trylock(d);
-
-   if (lock && d->driver)
-   name = d->driver->name;
-   dev_err(d, "Failed to re-probe to %s\n", name);
-   if (lock)
-   device_unlock(d);
-   }
-   put_device(d);
-   }
-   kvfree(dev);
-
notifier->v4l2_dev = NULL;
-
-   /*
-* Don't care about the waiting list, it is initialised and populated
-* upon notifier registration.
-*/
 }
 EXPORT_SYMBOL(v4l2_async_notifier_unregister);
 
-- 
2.11.0



[PATCH v11 10/24] v4l: async: Move async subdev notifier operations to a separate structure

2017-09-12 Thread Sakari Ailus
From: Laurent Pinchart 

The async subdev notifier .bound(), .unbind() and .complete() operations
are function pointers stored directly in the v4l2_async_subdev
structure. As the structure isn't immutable, this creates a potential
security risk as the function pointers are mutable.

To fix this, move the function pointers to a new
v4l2_async_subdev_operations structure that can be made const in
drivers.

Signed-off-by: Laurent Pinchart 
Acked-by: Hans Verkuil 
---
 drivers/media/platform/am437x/am437x-vpfe.c|  8 +--
 drivers/media/platform/atmel/atmel-isc.c   | 10 ++---
 drivers/media/platform/atmel/atmel-isi.c   | 10 ++---
 drivers/media/platform/davinci/vpif_capture.c  |  8 +--
 drivers/media/platform/davinci/vpif_display.c  |  8 +--
 drivers/media/platform/exynos4-is/media-dev.c  |  8 +--
 drivers/media/platform/omap3isp/isp.c  |  6 +-
 drivers/media/platform/pxa_camera.c|  8 +--
 drivers/media/platform/qcom/camss-8x16/camss.c |  8 +--
 drivers/media/platform/rcar-vin/rcar-core.c| 10 ++---
 drivers/media/platform/rcar_drif.c | 10 ++---
 drivers/media/platform/soc_camera/soc_camera.c | 14 +++--
 drivers/media/platform/stm32/stm32-dcmi.c  | 10 ++---
 drivers/media/platform/ti-vpe/cal.c|  8 +--
 drivers/media/platform/xilinx/xilinx-vipp.c|  8 +--
 drivers/media/v4l2-core/v4l2-async.c   | 20 +-
 drivers/staging/media/imx/imx-media-dev.c  |  8 +--
 include/media/v4l2-async.h | 29 +-
 18 files changed, 131 insertions(+), 60 deletions(-)

diff --git a/drivers/media/platform/am437x/am437x-vpfe.c 
b/drivers/media/platform/am437x/am437x-vpfe.c
index dfcc484cab89..0997c640191d 100644
--- a/drivers/media/platform/am437x/am437x-vpfe.c
+++ b/drivers/media/platform/am437x/am437x-vpfe.c
@@ -2417,6 +2417,11 @@ static int vpfe_async_complete(struct 
v4l2_async_notifier *notifier)
return vpfe_probe_complete(vpfe);
 }
 
+static const struct v4l2_async_notifier_operations vpfe_async_ops = {
+   .bound = vpfe_async_bound,
+   .complete = vpfe_async_complete,
+};
+
 static struct vpfe_config *
 vpfe_get_pdata(struct platform_device *pdev)
 {
@@ -2590,8 +2595,7 @@ static int vpfe_probe(struct platform_device *pdev)
 
vpfe->notifier.subdevs = vpfe->cfg->asd;
vpfe->notifier.num_subdevs = ARRAY_SIZE(vpfe->cfg->asd);
-   vpfe->notifier.bound = vpfe_async_bound;
-   vpfe->notifier.complete = vpfe_async_complete;
+   vpfe->notifier.ops = &vpfe_async_ops;
ret = v4l2_async_notifier_register(&vpfe->v4l2_dev,
&vpfe->notifier);
if (ret) {
diff --git a/drivers/media/platform/atmel/atmel-isc.c 
b/drivers/media/platform/atmel/atmel-isc.c
index d7103c5f92c3..48544c4137cb 100644
--- a/drivers/media/platform/atmel/atmel-isc.c
+++ b/drivers/media/platform/atmel/atmel-isc.c
@@ -1639,6 +1639,12 @@ static int isc_async_complete(struct v4l2_async_notifier 
*notifier)
return 0;
 }
 
+static const struct v4l2_async_notifier_operations isc_async_ops = {
+   .bound = isc_async_bound,
+   .unbind = isc_async_unbind,
+   .complete = isc_async_complete,
+};
+
 static void isc_subdev_cleanup(struct isc_device *isc)
 {
struct isc_subdev_entity *subdev_entity;
@@ -1851,9 +1857,7 @@ static int atmel_isc_probe(struct platform_device *pdev)
list_for_each_entry(subdev_entity, &isc->subdev_entities, list) {
subdev_entity->notifier.subdevs = &subdev_entity->asd;
subdev_entity->notifier.num_subdevs = 1;
-   subdev_entity->notifier.bound = isc_async_bound;
-   subdev_entity->notifier.unbind = isc_async_unbind;
-   subdev_entity->notifier.complete = isc_async_complete;
+   subdev_entity->notifier.ops = &isc_async_ops;
 
ret = v4l2_async_notifier_register(&isc->v4l2_dev,
   &subdev_entity->notifier);
diff --git a/drivers/media/platform/atmel/atmel-isi.c 
b/drivers/media/platform/atmel/atmel-isi.c
index 891fa2505efa..eadbf9def358 100644
--- a/drivers/media/platform/atmel/atmel-isi.c
+++ b/drivers/media/platform/atmel/atmel-isi.c
@@ -1105,6 +1105,12 @@ static int isi_graph_notify_bound(struct 
v4l2_async_notifier *notifier,
return 0;
 }
 
+static const struct v4l2_async_notifier_operations isi_graph_notify_ops = {
+   .bound = isi_graph_notify_bound,
+   .unbind = isi_graph_notify_unbind,
+   .complete = isi_graph_notify_complete,
+};
+
 static int isi_graph_parse(struct atmel_isi *isi, struct device_node *node)
 {
struct device_node *ep = NULL;
@@ -1152,9 +1158,7 @@ static int isi_graph_init(struct atmel_isi *isi)
 
isi->notifier.subdevs = subdevs;
isi->notifier.num_subdevs = 1;
-   isi->notifier.bound = isi_graph_notify_bound;
-  

[PATCH v11 07/24] rcar-vin: Use generic parser for parsing fwnode endpoints

2017-09-12 Thread Sakari Ailus
Instead of using driver implementation, use
v4l2_async_notifier_parse_fwnode_endpoints() to parse the fwnode endpoints
of the device.

Signed-off-by: Sakari Ailus 
Acked-by: Hans Verkuil 
---
 drivers/media/platform/rcar-vin/rcar-core.c | 112 +---
 drivers/media/platform/rcar-vin/rcar-dma.c  |  10 +--
 drivers/media/platform/rcar-vin/rcar-v4l2.c |  14 ++--
 drivers/media/platform/rcar-vin/rcar-vin.h  |   4 +-
 4 files changed, 48 insertions(+), 92 deletions(-)

diff --git a/drivers/media/platform/rcar-vin/rcar-core.c 
b/drivers/media/platform/rcar-vin/rcar-core.c
index 142de447..62b4a94f9a39 100644
--- a/drivers/media/platform/rcar-vin/rcar-core.c
+++ b/drivers/media/platform/rcar-vin/rcar-core.c
@@ -21,6 +21,7 @@
 #include 
 #include 
 
+#include 
 #include 
 
 #include "rcar-vin.h"
@@ -77,14 +78,14 @@ static int rvin_digital_notify_complete(struct 
v4l2_async_notifier *notifier)
int ret;
 
/* Verify subdevices mbus format */
-   if (!rvin_mbus_supported(&vin->digital)) {
+   if (!rvin_mbus_supported(vin->digital)) {
vin_err(vin, "Unsupported media bus format for %s\n",
-   vin->digital.subdev->name);
+   vin->digital->subdev->name);
return -EINVAL;
}
 
vin_dbg(vin, "Found media bus format for %s: %d\n",
-   vin->digital.subdev->name, vin->digital.code);
+   vin->digital->subdev->name, vin->digital->code);
 
ret = v4l2_device_register_subdev_nodes(&vin->v4l2_dev);
if (ret < 0) {
@@ -103,7 +104,7 @@ static void rvin_digital_notify_unbind(struct 
v4l2_async_notifier *notifier,
 
vin_dbg(vin, "unbind digital subdev %s\n", subdev->name);
rvin_v4l2_remove(vin);
-   vin->digital.subdev = NULL;
+   vin->digital->subdev = NULL;
 }
 
 static int rvin_digital_notify_bound(struct v4l2_async_notifier *notifier,
@@ -120,117 +121,70 @@ static int rvin_digital_notify_bound(struct 
v4l2_async_notifier *notifier,
ret = rvin_find_pad(subdev, MEDIA_PAD_FL_SOURCE);
if (ret < 0)
return ret;
-   vin->digital.source_pad = ret;
+   vin->digital->source_pad = ret;
 
ret = rvin_find_pad(subdev, MEDIA_PAD_FL_SINK);
-   vin->digital.sink_pad = ret < 0 ? 0 : ret;
+   vin->digital->sink_pad = ret < 0 ? 0 : ret;
 
-   vin->digital.subdev = subdev;
+   vin->digital->subdev = subdev;
 
vin_dbg(vin, "bound subdev %s source pad: %u sink pad: %u\n",
-   subdev->name, vin->digital.source_pad,
-   vin->digital.sink_pad);
+   subdev->name, vin->digital->source_pad,
+   vin->digital->sink_pad);
 
return 0;
 }
 
-static int rvin_digitial_parse_v4l2(struct rvin_dev *vin,
-   struct device_node *ep,
-   struct v4l2_mbus_config *mbus_cfg)
+static int rvin_digital_parse_v4l2(struct device *dev,
+  struct v4l2_fwnode_endpoint *vep,
+  struct v4l2_async_subdev *asd)
 {
-   struct v4l2_fwnode_endpoint v4l2_ep;
-   int ret;
+   struct rvin_dev *vin = dev_get_drvdata(dev);
+   struct rvin_graph_entity *rvge =
+   container_of(asd, struct rvin_graph_entity, asd);
 
-   ret = v4l2_fwnode_endpoint_parse(of_fwnode_handle(ep), &v4l2_ep);
-   if (ret) {
-   vin_err(vin, "Could not parse v4l2 endpoint\n");
-   return -EINVAL;
-   }
+   if (vep->base.port || vep->base.id)
+   return -ENOTCONN;
 
-   mbus_cfg->type = v4l2_ep.bus_type;
+   rvge->mbus_cfg.type = vep->bus_type;
 
-   switch (mbus_cfg->type) {
+   switch (rvge->mbus_cfg.type) {
case V4L2_MBUS_PARALLEL:
vin_dbg(vin, "Found PARALLEL media bus\n");
-   mbus_cfg->flags = v4l2_ep.bus.parallel.flags;
+   rvge->mbus_cfg.flags = vep->bus.parallel.flags;
break;
case V4L2_MBUS_BT656:
vin_dbg(vin, "Found BT656 media bus\n");
-   mbus_cfg->flags = 0;
+   rvge->mbus_cfg.flags = 0;
break;
default:
vin_err(vin, "Unknown media bus type\n");
return -EINVAL;
}
 
-   return 0;
-}
-
-static int rvin_digital_graph_parse(struct rvin_dev *vin)
-{
-   struct device_node *ep, *np;
-   int ret;
-
-   vin->digital.asd.match.fwnode.fwnode = NULL;
-   vin->digital.subdev = NULL;
-
-   /*
-* Port 0 id 0 is local digital input, try to get it.
-* Not all instances can or will have this, that is OK
-*/
-   ep = of_graph_get_endpoint_by_regs(vin->dev->of_node, 0, 0);
-   if (!ep)
-   return 0;
-
-   np = of_graph_get_remote_port_parent(ep);
-   if (!np) {
-   vin_err(vin, "No remote parent for digital input\n");
-   o

[PATCH v11 06/24] omap3isp: Use generic parser for parsing fwnode endpoints

2017-09-12 Thread Sakari Ailus
Instead of using driver implementation, use
v4l2_async_notifier_parse_fwnode_endpoints() to parse the fwnode endpoints
of the device.

Signed-off-by: Sakari Ailus 
Acked-by: Hans Verkuil 
---
 drivers/media/platform/omap3isp/isp.c | 115 +++---
 drivers/media/platform/omap3isp/isp.h |   5 +-
 2 files changed, 37 insertions(+), 83 deletions(-)

diff --git a/drivers/media/platform/omap3isp/isp.c 
b/drivers/media/platform/omap3isp/isp.c
index 1a428fe9f070..a546cf774d40 100644
--- a/drivers/media/platform/omap3isp/isp.c
+++ b/drivers/media/platform/omap3isp/isp.c
@@ -2001,6 +2001,7 @@ static int isp_remove(struct platform_device *pdev)
__omap3isp_put(isp, false);
 
media_entity_enum_cleanup(&isp->crashed);
+   v4l2_async_notifier_release(&isp->notifier);
 
return 0;
 }
@@ -2011,44 +2012,41 @@ enum isp_of_phy {
ISP_OF_PHY_CSIPHY2,
 };
 
-static int isp_fwnode_parse(struct device *dev, struct fwnode_handle *fwnode,
-   struct isp_async_subdev *isd)
+static int isp_fwnode_parse(struct device *dev,
+   struct v4l2_fwnode_endpoint *vep,
+   struct v4l2_async_subdev *asd)
 {
+   struct isp_async_subdev *isd =
+   container_of(asd, struct isp_async_subdev, asd);
struct isp_bus_cfg *buscfg = &isd->bus;
-   struct v4l2_fwnode_endpoint vep;
-   unsigned int i;
-   int ret;
bool csi1 = false;
-
-   ret = v4l2_fwnode_endpoint_parse(fwnode, &vep);
-   if (ret)
-   return ret;
+   unsigned int i;
 
dev_dbg(dev, "parsing endpoint %pOF, interface %u\n",
-   to_of_node(fwnode), vep.base.port);
+   to_of_node(vep->base.local_fwnode), vep->base.port);
 
-   switch (vep.base.port) {
+   switch (vep->base.port) {
case ISP_OF_PHY_PARALLEL:
buscfg->interface = ISP_INTERFACE_PARALLEL;
buscfg->bus.parallel.data_lane_shift =
-   vep.bus.parallel.data_shift;
+   vep->bus.parallel.data_shift;
buscfg->bus.parallel.clk_pol =
-   !!(vep.bus.parallel.flags
+   !!(vep->bus.parallel.flags
   & V4L2_MBUS_PCLK_SAMPLE_FALLING);
buscfg->bus.parallel.hs_pol =
-   !!(vep.bus.parallel.flags & V4L2_MBUS_VSYNC_ACTIVE_LOW);
+   !!(vep->bus.parallel.flags & 
V4L2_MBUS_VSYNC_ACTIVE_LOW);
buscfg->bus.parallel.vs_pol =
-   !!(vep.bus.parallel.flags & V4L2_MBUS_HSYNC_ACTIVE_LOW);
+   !!(vep->bus.parallel.flags & 
V4L2_MBUS_HSYNC_ACTIVE_LOW);
buscfg->bus.parallel.fld_pol =
-   !!(vep.bus.parallel.flags & V4L2_MBUS_FIELD_EVEN_LOW);
+   !!(vep->bus.parallel.flags & V4L2_MBUS_FIELD_EVEN_LOW);
buscfg->bus.parallel.data_pol =
-   !!(vep.bus.parallel.flags & V4L2_MBUS_DATA_ACTIVE_LOW);
-   buscfg->bus.parallel.bt656 = vep.bus_type == V4L2_MBUS_BT656;
+   !!(vep->bus.parallel.flags & V4L2_MBUS_DATA_ACTIVE_LOW);
+   buscfg->bus.parallel.bt656 = vep->bus_type == V4L2_MBUS_BT656;
break;
 
case ISP_OF_PHY_CSIPHY1:
case ISP_OF_PHY_CSIPHY2:
-   switch (vep.bus_type) {
+   switch (vep->bus_type) {
case V4L2_MBUS_CCP2:
case V4L2_MBUS_CSI1:
dev_dbg(dev, "CSI-1/CCP-2 configuration\n");
@@ -2060,11 +2058,11 @@ static int isp_fwnode_parse(struct device *dev, struct 
fwnode_handle *fwnode,
break;
default:
dev_err(dev, "unsupported bus type %u\n",
-   vep.bus_type);
+   vep->bus_type);
return -EINVAL;
}
 
-   switch (vep.base.port) {
+   switch (vep->base.port) {
case ISP_OF_PHY_CSIPHY1:
if (csi1)
buscfg->interface = ISP_INTERFACE_CCP2B_PHY1;
@@ -2080,47 +2078,47 @@ static int isp_fwnode_parse(struct device *dev, struct 
fwnode_handle *fwnode,
}
if (csi1) {
buscfg->bus.ccp2.lanecfg.clk.pos =
-   vep.bus.mipi_csi1.clock_lane;
+   vep->bus.mipi_csi1.clock_lane;
buscfg->bus.ccp2.lanecfg.clk.pol =
-   vep.bus.mipi_csi1.lane_polarity[0];
+   vep->bus.mipi_csi1.lane_polarity[0];
dev_dbg(dev, "clock lane polarity %u, pos %u\n",
buscfg->bus.ccp2.lanecfg.clk.pol,
buscfg->bus.ccp2.lanecfg.clk.pos);
 
   

[PATCH v11 21/24] smiapp: Add support for flash and lens devices

2017-09-12 Thread Sakari Ailus
Parse async sub-devices by using
v4l2_subdev_fwnode_reference_parse_sensor_common().

These types devices aren't directly related to the sensor, but are
nevertheless handled by the smiapp driver due to the relationship of these
component to the main part of the camera module --- the sensor.

This does not yet address providing the user space with information on how
to associate the sensor or lens devices but the kernel now has the
necessary information to do that.

Signed-off-by: Sakari Ailus 
Acked-by: Hans Verkuil 
---
 drivers/media/i2c/smiapp/smiapp-core.c | 38 +++---
 drivers/media/i2c/smiapp/smiapp.h  |  4 +++-
 2 files changed, 33 insertions(+), 9 deletions(-)

diff --git a/drivers/media/i2c/smiapp/smiapp-core.c 
b/drivers/media/i2c/smiapp/smiapp-core.c
index 700f433261d0..a65a839135d2 100644
--- a/drivers/media/i2c/smiapp/smiapp-core.c
+++ b/drivers/media/i2c/smiapp/smiapp-core.c
@@ -31,7 +31,7 @@
 #include 
 #include 
 #include 
-#include 
+#include 
 #include 
 #include 
 
@@ -2887,17 +2887,24 @@ static int smiapp_probe(struct i2c_client *client,
v4l2_i2c_subdev_init(&sensor->src->sd, client, &smiapp_ops);
sensor->src->sd.internal_ops = &smiapp_internal_src_ops;
 
+   rval = v4l2_fwnode_reference_parse_sensor_common(
+   &client->dev, &sensor->notifier);
+   if (rval < 0)
+   return rval;
+
sensor->vana = devm_regulator_get(&client->dev, "vana");
if (IS_ERR(sensor->vana)) {
dev_err(&client->dev, "could not get regulator for vana\n");
-   return PTR_ERR(sensor->vana);
+   rval = PTR_ERR(sensor->vana);
+   goto out_release_async_notifier;
}
 
sensor->ext_clk = devm_clk_get(&client->dev, NULL);
if (IS_ERR(sensor->ext_clk)) {
dev_err(&client->dev, "could not get clock (%ld)\n",
PTR_ERR(sensor->ext_clk));
-   return -EPROBE_DEFER;
+   rval = -EPROBE_DEFER;
+   goto out_release_async_notifier;
}
 
rval = clk_set_rate(sensor->ext_clk, sensor->hwcfg->ext_clk);
@@ -2905,17 +2912,19 @@ static int smiapp_probe(struct i2c_client *client,
dev_err(&client->dev,
"unable to set clock freq to %u\n",
sensor->hwcfg->ext_clk);
-   return rval;
+   goto out_release_async_notifier;
}
 
sensor->xshutdown = devm_gpiod_get_optional(&client->dev, "xshutdown",
GPIOD_OUT_LOW);
-   if (IS_ERR(sensor->xshutdown))
-   return PTR_ERR(sensor->xshutdown);
+   if (IS_ERR(sensor->xshutdown)) {
+   rval = PTR_ERR(sensor->xshutdown);
+   goto out_release_async_notifier;
+   }
 
rval = smiapp_power_on(&client->dev);
if (rval < 0)
-   return rval;
+   goto out_release_async_notifier;
 
rval = smiapp_identify_module(sensor);
if (rval) {
@@ -3092,9 +3101,14 @@ static int smiapp_probe(struct i2c_client *client,
if (rval < 0)
goto out_media_entity_cleanup;
 
+   rval = v4l2_async_subdev_notifier_register(&sensor->src->sd,
+  &sensor->notifier);
+   if (rval)
+   goto out_media_entity_cleanup;
+
rval = v4l2_async_register_subdev(&sensor->src->sd);
if (rval < 0)
-   goto out_media_entity_cleanup;
+   goto out_unregister_async_notifier;
 
pm_runtime_set_active(&client->dev);
pm_runtime_get_noresume(&client->dev);
@@ -3105,6 +3119,9 @@ static int smiapp_probe(struct i2c_client *client,
 
return 0;
 
+out_unregister_async_notifier:
+   v4l2_async_notifier_unregister(&sensor->notifier);
+
 out_media_entity_cleanup:
media_entity_cleanup(&sensor->src->sd.entity);
 
@@ -3114,6 +3131,9 @@ static int smiapp_probe(struct i2c_client *client,
 out_power_off:
smiapp_power_off(&client->dev);
 
+out_release_async_notifier:
+   v4l2_async_notifier_release(&sensor->notifier);
+
return rval;
 }
 
@@ -3124,6 +3144,8 @@ static int smiapp_remove(struct i2c_client *client)
unsigned int i;
 
v4l2_async_unregister_subdev(subdev);
+   v4l2_async_notifier_unregister(&sensor->notifier);
+   v4l2_async_notifier_release(&sensor->notifier);
 
pm_runtime_disable(&client->dev);
if (!pm_runtime_status_suspended(&client->dev))
diff --git a/drivers/media/i2c/smiapp/smiapp.h 
b/drivers/media/i2c/smiapp/smiapp.h
index f74d695018b9..be92cb5713f4 100644
--- a/drivers/media/i2c/smiapp/smiapp.h
+++ b/drivers/media/i2c/smiapp/smiapp.h
@@ -20,9 +20,10 @@
 #define __SMIAPP_PRIV_H_
 
 #include 
+#include 
+#include 
 #include 
 #include 
-#include 
 
 #include "smiapp-pll.h"
 #include "smiapp-reg.h"
@@ -172,6 +173,7 @@ struct smiapp_subdev {
  * st

[PATCH v11 16/24] dt: bindings: Add lens-focus binding for image sensors

2017-09-12 Thread Sakari Ailus
The lens-focus property contains a phandle to the lens voice coil driver
that is associated to the sensor; typically both are contained in the same
camera module.

Signed-off-by: Sakari Ailus 
Acked-by: Pavel Machek 
Reviewed-by: Sebastian Reichel 
Acked-by: Rob Herring 
Acked-by: Hans Verkuil 
---
 Documentation/devicetree/bindings/media/video-interfaces.txt | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/Documentation/devicetree/bindings/media/video-interfaces.txt 
b/Documentation/devicetree/bindings/media/video-interfaces.txt
index fdba30479b47..b535bdde861c 100644
--- a/Documentation/devicetree/bindings/media/video-interfaces.txt
+++ b/Documentation/devicetree/bindings/media/video-interfaces.txt
@@ -74,6 +74,8 @@ Optional properties
 - flash-leds: An array of phandles, each referring to a flash LED, a sub-node
   of the LED driver device node.
 
+- lens-focus: A phandle to the node of the focus lens controller.
+
 
 Optional endpoint properties
 
-- 
2.11.0



[PATCH v11 12/24] v4l: async: Register sub-devices before calling bound callback

2017-09-12 Thread Sakari Ailus
Register the sub-device before calling the notifier's bound callback.
Doing this the other way around is problematic as the struct v4l2_device
has not assigned for the sub-device yet and may be required by the bound
callback.

Signed-off-by: Sakari Ailus 
Acked-by: Hans Verkuil 
---
 drivers/media/v4l2-core/v4l2-async.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/media/v4l2-core/v4l2-async.c 
b/drivers/media/v4l2-core/v4l2-async.c
index c34f93593b41..7b396ff4302b 100644
--- a/drivers/media/v4l2-core/v4l2-async.c
+++ b/drivers/media/v4l2-core/v4l2-async.c
@@ -130,13 +130,13 @@ static int v4l2_async_match_notify(struct 
v4l2_async_notifier *notifier,
 {
int ret;
 
-   ret = v4l2_async_notifier_call_bound(notifier, sd, asd);
+   ret = v4l2_device_register_subdev(notifier->v4l2_dev, sd);
if (ret < 0)
return ret;
 
-   ret = v4l2_device_register_subdev(notifier->v4l2_dev, sd);
+   ret = v4l2_async_notifier_call_bound(notifier, sd, asd);
if (ret < 0) {
-   v4l2_async_notifier_call_unbind(notifier, sd, asd);
+   v4l2_device_unregister_subdev(sd);
return ret;
}
 
-- 
2.11.0



[PATCH v11 05/24] v4l: fwnode: Support generic parsing of graph endpoints in a device

2017-09-12 Thread Sakari Ailus
The current practice is that drivers iterate over their endpoints and
parse each endpoint separately. This is very similar in a number of
drivers, implement a generic function for the job. Driver specific matters
can be taken into account in the driver specific callback.

Signed-off-by: Sakari Ailus 
Acked-by: Hans Verkuil 
---
 drivers/media/v4l2-core/v4l2-async.c  |  30 
 drivers/media/v4l2-core/v4l2-fwnode.c | 136 ++
 include/media/v4l2-async.h|  24 +-
 include/media/v4l2-fwnode.h   |  56 ++
 4 files changed, 244 insertions(+), 2 deletions(-)

diff --git a/drivers/media/v4l2-core/v4l2-async.c 
b/drivers/media/v4l2-core/v4l2-async.c
index 831f185ecd47..ad099b9bb71d 100644
--- a/drivers/media/v4l2-core/v4l2-async.c
+++ b/drivers/media/v4l2-core/v4l2-async.c
@@ -22,6 +22,7 @@
 
 #include 
 #include 
+#include 
 #include 
 
 static bool match_i2c(struct v4l2_subdev *sd, struct v4l2_async_subdev *asd)
@@ -219,6 +220,35 @@ void v4l2_async_notifier_unregister(struct 
v4l2_async_notifier *notifier)
 }
 EXPORT_SYMBOL(v4l2_async_notifier_unregister);
 
+void v4l2_async_notifier_release(struct v4l2_async_notifier *notifier)
+{
+   unsigned int i;
+
+   if (!notifier->max_subdevs)
+   return;
+
+   for (i = 0; i < notifier->num_subdevs; i++) {
+   struct v4l2_async_subdev *asd = notifier->subdevs[i];
+
+   switch (asd->match_type) {
+   case V4L2_ASYNC_MATCH_FWNODE:
+   fwnode_handle_put(asd->match.fwnode.fwnode);
+   break;
+   default:
+   WARN_ON_ONCE(1);
+   }
+
+   kfree(asd);
+   }
+
+   notifier->max_subdevs = 0;
+   notifier->num_subdevs = 0;
+
+   kvfree(notifier->subdevs);
+   notifier->subdevs = NULL;
+}
+EXPORT_SYMBOL_GPL(v4l2_async_notifier_release);
+
 int v4l2_async_register_subdev(struct v4l2_subdev *sd)
 {
struct v4l2_async_notifier *notifier;
diff --git a/drivers/media/v4l2-core/v4l2-fwnode.c 
b/drivers/media/v4l2-core/v4l2-fwnode.c
index 706f9e7b90f1..d978f2d714ca 100644
--- a/drivers/media/v4l2-core/v4l2-fwnode.c
+++ b/drivers/media/v4l2-core/v4l2-fwnode.c
@@ -19,6 +19,7 @@
  */
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -26,6 +27,7 @@
 #include 
 #include 
 
+#include 
 #include 
 
 enum v4l2_fwnode_bus_type {
@@ -313,6 +315,140 @@ void v4l2_fwnode_put_link(struct v4l2_fwnode_link *link)
 }
 EXPORT_SYMBOL_GPL(v4l2_fwnode_put_link);
 
+static int v4l2_async_notifier_realloc(struct v4l2_async_notifier *notifier,
+  unsigned int max_subdevs)
+{
+   struct v4l2_async_subdev **subdevs;
+
+   if (max_subdevs <= notifier->max_subdevs)
+   return 0;
+
+   subdevs = kvmalloc_array(
+   max_subdevs, sizeof(*notifier->subdevs),
+   GFP_KERNEL | __GFP_ZERO);
+   if (!subdevs)
+   return -ENOMEM;
+
+   if (notifier->subdevs) {
+   memcpy(subdevs, notifier->subdevs,
+  sizeof(*subdevs) * notifier->num_subdevs);
+
+   kvfree(notifier->subdevs);
+   }
+
+   notifier->subdevs = subdevs;
+   notifier->max_subdevs = max_subdevs;
+
+   return 0;
+}
+
+static int v4l2_async_notifier_fwnode_parse_endpoint(
+   struct device *dev, struct v4l2_async_notifier *notifier,
+   struct fwnode_handle *endpoint, unsigned int asd_struct_size,
+   int (*parse_endpoint)(struct device *dev,
+   struct v4l2_fwnode_endpoint *vep,
+   struct v4l2_async_subdev *asd))
+{
+   struct v4l2_async_subdev *asd;
+   struct v4l2_fwnode_endpoint *vep;
+   int ret = 0;
+
+   asd = kzalloc(asd_struct_size, GFP_KERNEL);
+   if (!asd)
+   return -ENOMEM;
+
+   asd->match.fwnode.fwnode =
+   fwnode_graph_get_remote_port_parent(endpoint);
+   if (!asd->match.fwnode.fwnode) {
+   dev_warn(dev, "bad remote port parent\n");
+   ret = -EINVAL;
+   goto out_err;
+   }
+
+   /* Ignore endpoints the parsing of which failed. */
+   vep = v4l2_fwnode_endpoint_alloc_parse(endpoint);
+   if (IS_ERR(vep)) {
+   ret = PTR_ERR(vep);
+   dev_warn(dev, "unable to parse V4L2 fwnode endpoint (%d)\n",
+ret);
+   goto out_err;
+   }
+
+   ret = parse_endpoint ? parse_endpoint(dev, vep, asd) : 0;
+   if (ret == -ENOTCONN)
+   dev_dbg(dev, "ignoring endpoint %u,%u\n", vep->base.port,
+   vep->base.id);
+   else if (ret < 0)
+   dev_warn(dev, "driver could not parse endpoint %u,%u (%d)\n",
+vep->base.port, vep->base.id, ret);
+   v4l2_fwnode_endpoint_free(vep);
+   if (ret < 0)
+   goto out_err;
+
+   asd

[PATCH v11 13/24] v4l: async: Allow async notifier register call succeed with no subdevs

2017-09-12 Thread Sakari Ailus
The information on how many async sub-devices would be bindable to a
notifier is typically dependent on information from platform firmware and
it's not driver's business to be aware of that.

Many V4L2 main drivers are perfectly usable (and useful) without async
sub-devices and so if there aren't any around, just proceed call the
notifier's complete callback immediately without registering the notifier
itself.

If a driver needs to check whether there are async sub-devices available,
it can be done by inspecting the notifier's num_subdevs field which tells
the number of async sub-devices.

Signed-off-by: Sakari Ailus 
---
 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 7b396ff4302b..4525b03d59c1 100644
--- a/drivers/media/v4l2-core/v4l2-async.c
+++ b/drivers/media/v4l2-core/v4l2-async.c
@@ -170,14 +170,16 @@ int v4l2_async_notifier_register(struct v4l2_device 
*v4l2_dev,
struct v4l2_async_subdev *asd;
int i;
 
-   if (!v4l2_dev || !notifier->num_subdevs ||
-   notifier->num_subdevs > V4L2_MAX_SUBDEVS)
+   if (!v4l2_dev || notifier->num_subdevs > V4L2_MAX_SUBDEVS)
return -EINVAL;
 
notifier->v4l2_dev = v4l2_dev;
INIT_LIST_HEAD(¬ifier->waiting);
INIT_LIST_HEAD(¬ifier->done);
 
+   if (!notifier->num_subdevs)
+   return v4l2_async_notifier_call_complete(notifier);
+
for (i = 0; i < notifier->num_subdevs; i++) {
asd = notifier->subdevs[i];
 
-- 
2.11.0



[PATCH v11 23/24] ov13858: Add support for flash and lens devices

2017-09-12 Thread Sakari Ailus
Parse async sub-devices by using
v4l2_subdev_fwnode_reference_parse_sensor_common().

Signed-off-by: Sakari Ailus 
Acked-by: Hans Verkuil 
---
 drivers/media/i2c/ov13858.c | 26 +++---
 1 file changed, 23 insertions(+), 3 deletions(-)

diff --git a/drivers/media/i2c/ov13858.c b/drivers/media/i2c/ov13858.c
index af7af0d14c69..0d60defc7492 100644
--- a/drivers/media/i2c/ov13858.c
+++ b/drivers/media/i2c/ov13858.c
@@ -18,6 +18,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #define OV13858_REG_VALUE_08BIT1
 #define OV13858_REG_VALUE_16BIT2
@@ -1028,6 +1029,7 @@ static const struct ov13858_mode supported_modes[] = {
 struct ov13858 {
struct v4l2_subdev sd;
struct media_pad pad;
+   struct v4l2_async_notifier notifier;
 
struct v4l2_ctrl_handler ctrl_handler;
/* V4L2 Controls */
@@ -1715,6 +1717,11 @@ static int ov13858_probe(struct i2c_client *client,
if (!ov13858)
return -ENOMEM;
 
+   ret = v4l2_fwnode_reference_parse_sensor_common(
+   &client->dev, &ov13858->notifier);
+   if (ret < 0)
+   return ret;
+
/* Initialize subdev */
v4l2_i2c_subdev_init(&ov13858->sd, client, &ov13858_subdev_ops);
 
@@ -1722,7 +1729,7 @@ static int ov13858_probe(struct i2c_client *client,
ret = ov13858_identify_module(ov13858);
if (ret) {
dev_err(&client->dev, "failed to find sensor: %d\n", ret);
-   return ret;
+   goto error_notifier_release;
}
 
/* Set default mode to max resolution */
@@ -1730,7 +1737,7 @@ static int ov13858_probe(struct i2c_client *client,
 
ret = ov13858_init_controls(ov13858);
if (ret)
-   return ret;
+   goto error_notifier_release;
 
/* Initialize subdev */
ov13858->sd.internal_ops = &ov13858_internal_ops;
@@ -1746,9 +1753,14 @@ static int ov13858_probe(struct i2c_client *client,
goto error_handler_free;
}
 
+   ret = v4l2_async_subdev_notifier_register(&ov13858->sd,
+ &ov13858->notifier);
+   if (ret)
+   goto error_media_entity;
+
ret = v4l2_async_register_subdev(&ov13858->sd);
if (ret < 0)
-   goto error_media_entity;
+   goto error_notifier_unregister;
 
/*
 * Device is already turned on by i2c-core with ACPI domain PM.
@@ -1761,11 +1773,17 @@ static int ov13858_probe(struct i2c_client *client,
 
return 0;
 
+error_notifier_unregister:
+   v4l2_async_notifier_unregister(&ov13858->notifier);
+
 error_media_entity:
media_entity_cleanup(&ov13858->sd.entity);
 
 error_handler_free:
ov13858_free_controls(ov13858);
+
+error_notifier_release:
+   v4l2_async_notifier_release(&ov13858->notifier);
dev_err(&client->dev, "%s failed:%d\n", __func__, ret);
 
return ret;
@@ -1777,6 +1795,8 @@ static int ov13858_remove(struct i2c_client *client)
struct ov13858 *ov13858 = to_ov13858(sd);
 
v4l2_async_unregister_subdev(sd);
+   v4l2_async_notifier_unregister(&ov13858->notifier);
+   v4l2_async_notifier_release(&ov13858->notifier);
media_entity_cleanup(&sd->entity);
ov13858_free_controls(ov13858);
 
-- 
2.11.0



[PATCH v11 11/24] v4l: async: Introduce helpers for calling async ops callbacks

2017-09-12 Thread Sakari Ailus
Add three helper functions to call async operations callbacks. Besides
simplifying callbacks, this allows async notifiers to have no ops set,
i.e. it can be left NULL.

Signed-off-by: Sakari Ailus 
---
 drivers/media/v4l2-core/v4l2-async.c | 49 ++--
 include/media/v4l2-async.h   |  1 +
 2 files changed, 37 insertions(+), 13 deletions(-)

diff --git a/drivers/media/v4l2-core/v4l2-async.c 
b/drivers/media/v4l2-core/v4l2-async.c
index a2df85ea00f4..c34f93593b41 100644
--- a/drivers/media/v4l2-core/v4l2-async.c
+++ b/drivers/media/v4l2-core/v4l2-async.c
@@ -25,6 +25,34 @@
 #include 
 #include 
 
+static int v4l2_async_notifier_call_bound(struct v4l2_async_notifier *n,
+ struct v4l2_subdev *subdev,
+ struct v4l2_async_subdev *asd)
+{
+   if (!n->ops || !n->ops->bound)
+   return 0;
+
+   return n->ops->bound(n, subdev, asd);
+}
+
+static void v4l2_async_notifier_call_unbind(struct v4l2_async_notifier *n,
+   struct v4l2_subdev *subdev,
+   struct v4l2_async_subdev *asd)
+{
+   if (!n->ops || !n->ops->unbind)
+   return;
+
+   n->ops->unbind(n, subdev, asd);
+}
+
+static int v4l2_async_notifier_call_complete(struct v4l2_async_notifier *n)
+{
+   if (!n->ops || !n->ops->complete)
+   return 0;
+
+   return n->ops->complete(n);
+}
+
 static bool match_i2c(struct v4l2_subdev *sd, struct v4l2_async_subdev *asd)
 {
 #if IS_ENABLED(CONFIG_I2C)
@@ -102,16 +130,13 @@ static int v4l2_async_match_notify(struct 
v4l2_async_notifier *notifier,
 {
int ret;
 
-   if (notifier->ops->bound) {
-   ret = notifier->ops->bound(notifier, sd, asd);
-   if (ret < 0)
-   return ret;
-   }
+   ret = v4l2_async_notifier_call_bound(notifier, sd, asd);
+   if (ret < 0)
+   return ret;
 
ret = v4l2_device_register_subdev(notifier->v4l2_dev, sd);
if (ret < 0) {
-   if (notifier->ops->unbind)
-   notifier->ops->unbind(notifier, sd, asd);
+   v4l2_async_notifier_call_unbind(notifier, sd, asd);
return ret;
}
 
@@ -123,8 +148,8 @@ static int v4l2_async_match_notify(struct 
v4l2_async_notifier *notifier,
/* Move from the global subdevice list to notifier's done */
list_move(&sd->async_list, ¬ifier->done);
 
-   if (list_empty(¬ifier->waiting) && notifier->ops->complete)
-   return notifier->ops->complete(notifier);
+   if (list_empty(¬ifier->waiting))
+   return v4l2_async_notifier_call_complete(notifier);
 
return 0;
 }
@@ -210,8 +235,7 @@ void v4l2_async_notifier_unregister(struct 
v4l2_async_notifier *notifier)
list_for_each_entry_safe(sd, tmp, ¬ifier->done, async_list) {
v4l2_async_cleanup(sd);
 
-   if (notifier->ops->unbind)
-   notifier->ops->unbind(notifier, sd, sd->asd);
+   v4l2_async_notifier_call_unbind(notifier, sd, sd->asd);
}
 
mutex_unlock(&list_lock);
@@ -300,8 +324,7 @@ void v4l2_async_unregister_subdev(struct v4l2_subdev *sd)
 
v4l2_async_cleanup(sd);
 
-   if (notifier->ops->unbind)
-   notifier->ops->unbind(notifier, sd, sd->asd);
+   v4l2_async_notifier_call_unbind(notifier, sd, sd->asd);
 
mutex_unlock(&list_lock);
 }
diff --git a/include/media/v4l2-async.h b/include/media/v4l2-async.h
index 3c48f8b66d12..3bc8a7c0d83f 100644
--- a/include/media/v4l2-async.h
+++ b/include/media/v4l2-async.h
@@ -164,4 +164,5 @@ int v4l2_async_register_subdev(struct v4l2_subdev *sd);
  * @sd: pointer to &struct v4l2_subdev
  */
 void v4l2_async_unregister_subdev(struct v4l2_subdev *sd);
+
 #endif
-- 
2.11.0



[PATCH v11 24/24] arm: dts: omap3: N9/N950: Add flash references to the camera

2017-09-12 Thread Sakari Ailus
Add flash and indicator LED phandles to the sensor node.

Signed-off-by: Sakari Ailus 
Acked-by: Hans Verkuil 
Acked-by: Pavel Machek 
---
 arch/arm/boot/dts/omap3-n9.dts   | 1 +
 arch/arm/boot/dts/omap3-n950-n9.dtsi | 4 ++--
 arch/arm/boot/dts/omap3-n950.dts | 1 +
 3 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/arch/arm/boot/dts/omap3-n9.dts b/arch/arm/boot/dts/omap3-n9.dts
index b9e58c536afd..39e35f8b8206 100644
--- a/arch/arm/boot/dts/omap3-n9.dts
+++ b/arch/arm/boot/dts/omap3-n9.dts
@@ -26,6 +26,7 @@
clocks = <&isp 0>;
clock-frequency = <960>;
nokia,nvm-size = <(16 * 64)>;
+   flash-leds = <&as3645a_flash &as3645a_indicator>;
port {
smia_1_1: endpoint {
link-frequencies = /bits/ 64 <19920 
21000 49920>;
diff --git a/arch/arm/boot/dts/omap3-n950-n9.dtsi 
b/arch/arm/boot/dts/omap3-n950-n9.dtsi
index 1b0bd72945f2..12fbb3da5fce 100644
--- a/arch/arm/boot/dts/omap3-n950-n9.dtsi
+++ b/arch/arm/boot/dts/omap3-n950-n9.dtsi
@@ -271,14 +271,14 @@
#size-cells = <0>;
reg = <0x30>;
compatible = "ams,as3645a";
-   flash@0 {
+   as3645a_flash: flash@0 {
reg = <0x0>;
flash-timeout-us = <15>;
flash-max-microamp = <32>;
led-max-microamp = <6>;
ams,input-max-microamp = <175>;
};
-   indicator@1 {
+   as3645a_indicator: indicator@1 {
reg = <0x1>;
led-max-microamp = <1>;
};
diff --git a/arch/arm/boot/dts/omap3-n950.dts b/arch/arm/boot/dts/omap3-n950.dts
index 646601a3ebd8..c354a1ed1e70 100644
--- a/arch/arm/boot/dts/omap3-n950.dts
+++ b/arch/arm/boot/dts/omap3-n950.dts
@@ -60,6 +60,7 @@
clocks = <&isp 0>;
clock-frequency = <960>;
nokia,nvm-size = <(16 * 64)>;
+   flash-leds = <&as3645a_flash &as3645a_indicator>;
port {
smia_1_1: endpoint {
link-frequencies = /bits/ 64 <21000 
33360 39840>;
-- 
2.11.0



[PATCH v11 00/24] Unified fwnode endpoint parser, async sub-device notifier support, N9 flash DTS

2017-09-12 Thread Sakari Ailus
Hi folks,

We have a large influx of new, unmerged, drivers that are now parsing
fwnode endpoints and each one of them is doing this a little bit
differently. The needs are still exactly the same for the graph data
structure is device independent. This is still a non-trivial task and the
majority of the driver implementations are buggy, just buggy in different
ways.

Facilitate parsing endpoints by adding a convenience function for parsing
the endpoints, and make the omap3isp and rcar-vin drivers use them as an
example.

To show where we're getting with this, I've added support for async
sub-device notifier support that is notifiers that can be registered by
sub-device drivers as well as V4L2 fwnode improvements to make use of them
and the DTS changes for the Nokia N9. Some of these patches I've posted
previously in this set here:

http://www.spinics.net/lists/linux-media/msg118764.html>

Since that, the complete callback of the master notifier registering the
V4L2 device is only called once all sub-notifiers have been completed as
well. This way the device node creation can be postponed until all devices
have been successfully initialised.

With this, the as3645a driver successfully registers a sub-device to the
media device created by the omap3isp driver. The kernel also has the
information it's related to the sensor driven by the smiapp driver but we
don't have a way to expose that information yet.

since v10:

- Rename v4l2_async_get_subdev_notifier as
  v4l2_async_find_subdev_notifier, as this is what it effectively does:
  finds a notifier for a sub-device. Same for v4l2_async_notifier_get_v4l2_dev
  / v4l2_async_notifier_get_v4l2_dev.

- Initialise lists before calling v4l2_async_notifier_call_complete() if
  there are no sub-devices in a notifier.

- Warn on missing sub-device or existing v4l2_device on sub-device
  notifier register, and conversely missing v4l2_device or existing
  sub-device for a master notifier.

- Set notifier's sd and v4l2_dev fields NULL when the sub-device is
  unregistered.

- Document the newly added helper functions for parsing external
  references in v4l2-fwnode.c better.

- Return -ENOENT in v4l2_fwnode_reference_parse if no entries are found,
  and other errors as they occur.

- Turn the loop in v4l2_fwnode_reference_get_int_prop a while loop (was
  for).

- Don't put fwnodes in v4l2_fwnode_reference_parse_int_props.

- Fix description of parent field in struct v4l2_async_notifier.

- In the documentation of v4l2_async_notifier_release, document that this
  function must be called also after
  v4l2_fwnode_reference_parse_sensor_common, not just
  v4l2_async_notifier_parse_fwnode_endpoints. The same goes for
  v4l2_async_notifier_parse_fwnode_endpoints as well as
  v4l2_fwnode_reference_parse_sensor_common.

since v9:

- Drop "as3645a: Switch to fwnode property API" and "ACPI: Document how to
  refer to LEDs from remote nodes" patches. They're better off separately
  from this set.

- Address property documentation redundancy in smiapp DT binding
  documentation.

- Add patches "ov5670: Add support for flash and lens devices" and
  "ov13858: Add support for flash and lens devices".

since v8:

- Improve terminology for notifiers. Instead of master / subdev, we
  have root, parent and subdev notifiers.

- Renamed "flash" property as "flash-leds". There are many, and currently
  we make assumptions in a lot of places (e.g. LED bindings) that these
  are LEDs. While we don't have any other types of flashes supported right
  now (e.g. Xenon), it's safer to assume we might have them in the future.

- Use ENOTCONN instead of EPERM to tell from driver's callback function
  that an endpoint is to be skipped but not handled as an error.

- Avoid accessing notifier's subdevs array as well as num_subdevs field
  from rcar-vin driver.

- Add a patch "v4l: async: Allow async notifier register call succeed with no
  subdevs", which allows, well, what the subject says.

- Move checks for subdev / v4l2_dev from __v4l2_async_notifier_register()
  to v4l2_async_notifier_register() and
  v4l2_async_subdev_notifier_register().

- Don't initialise notifier->list. There was no need to do so, as this is
  the entry added to the list and not used otherwise. I.e. regarding this,
  the state before this patchset is restored.

- Clean up error handling in v4l2_async_notifier_fwnode_parse_endpoint().

- WARN_ON() in v4l2_async_notifier_parse_fwnode_endpoints() if the
  asd_struct_size is smaller than size of struct v4l2_async_subdev.

- Make v4l2_fwnode_reference_parse() static as there should be no need to
  use it outside the V4L2 fwnode framework. Also, remove the callback
  function as well as other arguments that always have the same value in
  current usage. (This can be changed later on if needed without affecting
  drivers.)

- Add the patch "v4l: fwnode: Add a helper function to obtain device /
  interger references", which allows similar use than
  v4l2_fwnode_reference_parse() but is 

[PATCH v11 08/24] omap3isp: Fix check for our own sub-devices

2017-09-12 Thread Sakari Ailus
We only want to link sub-devices that were bound to the async notifier the
isp driver registered but there may be other sub-devices in the
v4l2_device as well. Check for the correct async notifier.

Signed-off-by: Sakari Ailus 
Acked-by: Hans Verkuil 
Acked-by: Pavel Machek 
---
 drivers/media/platform/omap3isp/isp.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/media/platform/omap3isp/isp.c 
b/drivers/media/platform/omap3isp/isp.c
index a546cf774d40..3b1a9cd0e591 100644
--- a/drivers/media/platform/omap3isp/isp.c
+++ b/drivers/media/platform/omap3isp/isp.c
@@ -2155,7 +2155,7 @@ static int isp_subdev_notifier_complete(struct 
v4l2_async_notifier *async)
return ret;
 
list_for_each_entry(sd, &v4l2_dev->subdevs, list) {
-   if (!sd->asd)
+   if (sd->notifier != &isp->notifier)
continue;
 
ret = isp_link_entity(isp, &sd->entity,
-- 
2.11.0



[PATCH v11 15/24] dt: bindings: Add a binding for flash LED devices associated to a sensor

2017-09-12 Thread Sakari Ailus
Camera flash drivers (and LEDs) are separate from the sensor devices in
DT. In order to make an association between the two, provide the
association information to the software.

Signed-off-by: Sakari Ailus 
Acked-by: Rob Herring 
Acked-by: Hans Verkuil 
Acked-by: Pavel Machek 
---
 Documentation/devicetree/bindings/media/video-interfaces.txt | 8 
 1 file changed, 8 insertions(+)

diff --git a/Documentation/devicetree/bindings/media/video-interfaces.txt 
b/Documentation/devicetree/bindings/media/video-interfaces.txt
index 852041a7480c..fdba30479b47 100644
--- a/Documentation/devicetree/bindings/media/video-interfaces.txt
+++ b/Documentation/devicetree/bindings/media/video-interfaces.txt
@@ -67,6 +67,14 @@ are required in a relevant parent node:
identifier, should be 1.
  - #size-cells: should be zero.
 
+
+Optional properties
+---
+
+- flash-leds: An array of phandles, each referring to a flash LED, a sub-node
+  of the LED driver device node.
+
+
 Optional endpoint properties
 
 
-- 
2.11.0



[PATCH v11 14/24] v4l: async: Allow binding notifiers to sub-devices

2017-09-12 Thread Sakari Ailus
Registering a notifier has required the knowledge of struct v4l2_device
for the reason that sub-devices generally are registered to the
v4l2_device (as well as the media device, also available through
v4l2_device).

This information is not available for sub-device drivers at probe time.

What this patch does is that it allows registering notifiers without
having v4l2_device around. Instead the sub-device pointer is stored in the
notifier. Once the sub-device of the driver that registered the notifier
is registered, the notifier will gain the knowledge of the v4l2_device,
and the binding of async sub-devices from the sub-device driver's notifier
may proceed.

The root notifier's complete callback is only called when all sub-device
notifiers are completed.

Signed-off-by: Sakari Ailus 
---
 drivers/media/v4l2-core/v4l2-async.c | 219 ++-
 include/media/v4l2-async.h   |  16 ++-
 2 files changed, 204 insertions(+), 31 deletions(-)

diff --git a/drivers/media/v4l2-core/v4l2-async.c 
b/drivers/media/v4l2-core/v4l2-async.c
index 4525b03d59c1..5082b01d2b96 100644
--- a/drivers/media/v4l2-core/v4l2-async.c
+++ b/drivers/media/v4l2-core/v4l2-async.c
@@ -53,6 +53,10 @@ static int v4l2_async_notifier_call_complete(struct 
v4l2_async_notifier *n)
return n->ops->complete(n);
 }
 
+static int v4l2_async_match_notify(struct v4l2_async_notifier *notifier,
+  struct v4l2_subdev *sd,
+  struct v4l2_async_subdev *asd);
+
 static bool match_i2c(struct v4l2_subdev *sd, struct v4l2_async_subdev *asd)
 {
 #if IS_ENABLED(CONFIG_I2C)
@@ -124,14 +128,128 @@ static struct v4l2_async_subdev *v4l2_async_find_match(
return NULL;
 }
 
+/* Find the sub-device notifier registered by a sub-device driver. */
+static struct v4l2_async_notifier *v4l2_async_find_subdev_notifier(
+   struct v4l2_subdev *sd)
+{
+   struct v4l2_async_notifier *n;
+
+   list_for_each_entry(n, ¬ifier_list, list)
+   if (n->sd == sd)
+   return n;
+
+   return NULL;
+}
+
+/* Return true if all sub-device notifiers are complete, false otherwise. */
+static bool v4l2_async_subdev_notifiers_complete(
+   struct v4l2_async_notifier *notifier)
+{
+   struct v4l2_subdev *sd;
+
+   if (!list_empty(¬ifier->waiting))
+   return false;
+
+   list_for_each_entry(sd, ¬ifier->done, async_list) {
+   struct v4l2_async_notifier *subdev_notifier =
+   v4l2_async_find_subdev_notifier(sd);
+
+   if (!subdev_notifier)
+   continue;
+
+   if (!v4l2_async_subdev_notifiers_complete(subdev_notifier))
+   return false;
+   }
+
+   return true;
+}
+
+/* Get v4l2_device related to the notifier if one can be found. */
+static struct v4l2_device *v4l2_async_notifier_find_v4l2_dev(
+   struct v4l2_async_notifier *notifier)
+{
+   while (notifier->parent)
+   notifier = notifier->parent;
+
+   return notifier->v4l2_dev;
+}
+
+/* Test all async sub-devices in a notifier for a match. */
+static int v4l2_async_notifier_try_all_subdevs(
+   struct v4l2_async_notifier *notifier)
+{
+   struct v4l2_subdev *sd;
+
+   if (!v4l2_async_notifier_find_v4l2_dev(notifier))
+   return 0;
+
+again:
+   list_for_each_entry(sd, &subdev_list, async_list) {
+   struct v4l2_async_subdev *asd;
+   int ret;
+
+   asd = v4l2_async_find_match(notifier, sd);
+   if (!asd)
+   continue;
+
+   ret = v4l2_async_match_notify(notifier, sd, asd);
+   if (ret < 0)
+   return ret;
+
+   /*
+* v4l2_async_match_notify() may lead to registering a
+* new notifier and thus changing the async subdevs
+* list. In order to proceed safely from here, restart
+* parsing the list from the beginning.
+*/
+   goto again;
+   }
+
+   return 0;
+}
+
+/* Try completing a notifier. */
+static int v4l2_async_notifier_try_complete(
+   struct v4l2_async_notifier *notifier)
+{
+   do {
+   int ret;
+
+   /* Any local async sub-devices left? */
+   if (!list_empty(¬ifier->waiting))
+   return 0;
+
+   /*
+* Any sub-device notifiers waiting for async subdevs
+* to be bound?
+*/
+   if (!v4l2_async_subdev_notifiers_complete(notifier))
+   return 0;
+
+   /* Proceed completing the notifier */
+   ret = v4l2_async_notifier_call_complete(notifier);
+   if (ret < 0)
+   return ret;
+
+   /*
+* Obtain notifier's parent. If there is one, repeat
+  

[PATCH v11 04/24] v4l: async: Add V4L2 async documentation to the documentation build

2017-09-12 Thread Sakari Ailus
The V4L2 async wasn't part of the documentation build. Fix this.

Signed-off-by: Sakari Ailus 
Reviewed-by: Niklas Söderlund 
Acked-by: Hans Verkuil 
Reviewed-by: Laurent Pinchart 
---
 Documentation/media/kapi/v4l2-async.rst | 3 +++
 Documentation/media/kapi/v4l2-core.rst  | 1 +
 2 files changed, 4 insertions(+)
 create mode 100644 Documentation/media/kapi/v4l2-async.rst

diff --git a/Documentation/media/kapi/v4l2-async.rst 
b/Documentation/media/kapi/v4l2-async.rst
new file mode 100644
index ..523ff9eb09a0
--- /dev/null
+++ b/Documentation/media/kapi/v4l2-async.rst
@@ -0,0 +1,3 @@
+V4L2 async kAPI
+^^^
+.. kernel-doc:: include/media/v4l2-async.h
diff --git a/Documentation/media/kapi/v4l2-core.rst 
b/Documentation/media/kapi/v4l2-core.rst
index c7434f38fd9c..5cf292037a48 100644
--- a/Documentation/media/kapi/v4l2-core.rst
+++ b/Documentation/media/kapi/v4l2-core.rst
@@ -19,6 +19,7 @@ Video4Linux devices
 v4l2-mc
 v4l2-mediabus
 v4l2-mem2mem
+v4l2-async
 v4l2-fwnode
 v4l2-rect
 v4l2-tuner
-- 
2.11.0



[PATCH v11 01/24] v4l: fwnode: Move KernelDoc documentation to the header

2017-09-12 Thread Sakari Ailus
In V4L2 the practice is to have the KernelDoc documentation in the header
and not in .c source code files. This consequently makes the V4L2 fwnode
function documentation part of the Media documentation build.

Also correct the link related function and argument naming in
documentation.

Signed-off-by: Sakari Ailus 
Reviewed-by: Niklas Söderlund 
Acked-by: Hans Verkuil 
Acked-by: Pavel Machek 
---
 drivers/media/v4l2-core/v4l2-fwnode.c | 75 
 include/media/v4l2-fwnode.h   | 81 ++-
 2 files changed, 80 insertions(+), 76 deletions(-)

diff --git a/drivers/media/v4l2-core/v4l2-fwnode.c 
b/drivers/media/v4l2-core/v4l2-fwnode.c
index 40b2fbfe8865..706f9e7b90f1 100644
--- a/drivers/media/v4l2-core/v4l2-fwnode.c
+++ b/drivers/media/v4l2-core/v4l2-fwnode.c
@@ -181,25 +181,6 @@ v4l2_fwnode_endpoint_parse_csi1_bus(struct fwnode_handle 
*fwnode,
vep->bus_type = V4L2_MBUS_CSI1;
 }
 
-/**
- * v4l2_fwnode_endpoint_parse() - parse all fwnode node properties
- * @fwnode: pointer to the endpoint's fwnode handle
- * @vep: pointer to the V4L2 fwnode data structure
- *
- * All properties are optional. If none are found, we don't set any flags. This
- * means the port has a static configuration and no properties have to be
- * specified explicitly. If any properties that identify the bus as parallel
- * are found and slave-mode isn't set, we set V4L2_MBUS_MASTER. Similarly, if
- * we recognise the bus as serial CSI-2 and clock-noncontinuous isn't set, we
- * set the V4L2_MBUS_CSI2_CONTINUOUS_CLOCK flag. The caller should hold a
- * reference to @fwnode.
- *
- * NOTE: This function does not parse properties the size of which is variable
- * without a low fixed limit. Please use v4l2_fwnode_endpoint_alloc_parse() in
- * new drivers instead.
- *
- * Return: 0 on success or a negative error code on failure.
- */
 int v4l2_fwnode_endpoint_parse(struct fwnode_handle *fwnode,
   struct v4l2_fwnode_endpoint *vep)
 {
@@ -239,14 +220,6 @@ int v4l2_fwnode_endpoint_parse(struct fwnode_handle 
*fwnode,
 }
 EXPORT_SYMBOL_GPL(v4l2_fwnode_endpoint_parse);
 
-/*
- * v4l2_fwnode_endpoint_free() - free the V4L2 fwnode acquired by
- * v4l2_fwnode_endpoint_alloc_parse()
- * @vep - the V4L2 fwnode the resources of which are to be released
- *
- * It is safe to call this function with NULL argument or on a V4L2 fwnode the
- * parsing of which failed.
- */
 void v4l2_fwnode_endpoint_free(struct v4l2_fwnode_endpoint *vep)
 {
if (IS_ERR_OR_NULL(vep))
@@ -257,29 +230,6 @@ void v4l2_fwnode_endpoint_free(struct v4l2_fwnode_endpoint 
*vep)
 }
 EXPORT_SYMBOL_GPL(v4l2_fwnode_endpoint_free);
 
-/**
- * v4l2_fwnode_endpoint_alloc_parse() - parse all fwnode node properties
- * @fwnode: pointer to the endpoint's fwnode handle
- *
- * All properties are optional. If none are found, we don't set any flags. This
- * means the port has a static configuration and no properties have to be
- * specified explicitly. If any properties that identify the bus as parallel
- * are found and slave-mode isn't set, we set V4L2_MBUS_MASTER. Similarly, if
- * we recognise the bus as serial CSI-2 and clock-noncontinuous isn't set, we
- * set the V4L2_MBUS_CSI2_CONTINUOUS_CLOCK flag. The caller should hold a
- * reference to @fwnode.
- *
- * v4l2_fwnode_endpoint_alloc_parse() has two important differences to
- * v4l2_fwnode_endpoint_parse():
- *
- * 1. It also parses variable size data.
- *
- * 2. The memory it has allocated to store the variable size data must be freed
- *using v4l2_fwnode_endpoint_free() when no longer needed.
- *
- * Return: Pointer to v4l2_fwnode_endpoint if successful, on an error pointer
- * on error.
- */
 struct v4l2_fwnode_endpoint *v4l2_fwnode_endpoint_alloc_parse(
struct fwnode_handle *fwnode)
 {
@@ -322,24 +272,6 @@ struct v4l2_fwnode_endpoint 
*v4l2_fwnode_endpoint_alloc_parse(
 }
 EXPORT_SYMBOL_GPL(v4l2_fwnode_endpoint_alloc_parse);
 
-/**
- * v4l2_fwnode_endpoint_parse_link() - parse a link between two endpoints
- * @__fwnode: pointer to the endpoint's fwnode at the local end of the link
- * @link: pointer to the V4L2 fwnode link data structure
- *
- * Fill the link structure with the local and remote nodes and port numbers.
- * The local_node and remote_node fields are set to point to the local and
- * remote port's parent nodes respectively (the port parent node being the
- * parent node of the port node if that node isn't a 'ports' node, or the
- * grand-parent node of the port node otherwise).
- *
- * A reference is taken to both the local and remote nodes, the caller must use
- * v4l2_fwnode_endpoint_put_link() to drop the references when done with the
- * link.
- *
- * Return: 0 on success, or -ENOLINK if the remote endpoint fwnode can't be
- * found.
- */
 int v4l2_fwnode_parse_link(struct fwnode_handle *__fwnode,
   struct v4l2_fwnode_link *link)
 {
@@ -374,13 +306,6 @@ int v4l2_fwnode_p

[PATCH v11 09/24] omap3isp: Print the name of the entity where no source pads could be found

2017-09-12 Thread Sakari Ailus
If no source pads are found in an entity, print the name of the entity.

Signed-off-by: Sakari Ailus 
Acked-by: Hans Verkuil 
Acked-by: Pavel Machek 
---
 drivers/media/platform/omap3isp/isp.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/media/platform/omap3isp/isp.c 
b/drivers/media/platform/omap3isp/isp.c
index 3b1a9cd0e591..9a694924e46e 100644
--- a/drivers/media/platform/omap3isp/isp.c
+++ b/drivers/media/platform/omap3isp/isp.c
@@ -1669,8 +1669,8 @@ static int isp_link_entity(
break;
}
if (i == entity->num_pads) {
-   dev_err(isp->dev, "%s: no source pad in external entity\n",
-   __func__);
+   dev_err(isp->dev, "%s: no source pad in external entity %s\n",
+   __func__, entity->name);
return -EINVAL;
}
 
-- 
2.11.0



[PATCH v11 18/24] v4l: fwnode: Add a helper function to obtain device / interger references

2017-09-12 Thread Sakari Ailus
v4l2_fwnode_reference_parse_int_prop() will find an fwnode such that under
the device's own fwnode, it will follow child fwnodes with the given
property -- value pair and return the resulting fwnode.

Signed-off-by: Sakari Ailus 
---
 drivers/media/v4l2-core/v4l2-fwnode.c | 145 ++
 1 file changed, 145 insertions(+)

diff --git a/drivers/media/v4l2-core/v4l2-fwnode.c 
b/drivers/media/v4l2-core/v4l2-fwnode.c
index a61c16b337a0..93bd9c29fd43 100644
--- a/drivers/media/v4l2-core/v4l2-fwnode.c
+++ b/drivers/media/v4l2-core/v4l2-fwnode.c
@@ -518,6 +518,151 @@ static int v4l2_fwnode_reference_parse(
return ret;
 }
 
+/*
+ * v4l2_fwnode_reference_get_int_prop - parse a reference with integer
+ * arguments
+ * @dev: struct device pointer
+ * @notifier: notifier for @dev
+ * @prop: the name of the property
+ * @props: the array of integer property names
+ * @nprops: the number of integer properties
+ *
+ * Find fwnodes referred to by a property @prop, then under that iteratively
+ * follow each child node which has a property the value matches the integer
+ * argument at an index.
+ *
+ * Return: 0 on success
+ *-ENOENT if no entries (or the property itself) were found
+ *-EINVAL if property parsing otherwisefailed
+ *-ENOMEM if memory allocation failed
+ */
+static struct fwnode_handle *v4l2_fwnode_reference_get_int_prop(
+   struct fwnode_handle *fwnode, const char *prop, unsigned int index,
+   const char **props, unsigned int nprops)
+{
+   struct fwnode_reference_args fwnode_args;
+   unsigned int *args = fwnode_args.args;
+   struct fwnode_handle *child;
+   int ret;
+
+   /*
+* Obtain remote fwnode as well as the integer arguments.
+*
+* To-do: handle -ENODATA when "device property: Align return
+* codes of acpi_fwnode_get_reference_with_args" is merged.
+*/
+   ret = fwnode_property_get_reference_args(fwnode, prop, NULL, nprops,
+index, &fwnode_args);
+   if (ret)
+   return ERR_PTR(ret == -ENODATA ? -ENOENT : ret);
+
+   /*
+* Find a node in the tree under the referred fwnode corresponding the
+* integer arguments.
+*/
+   fwnode = fwnode_args.fwnode;
+   while (nprops) {
+   u32 val;
+
+   /* Loop over all child nodes under fwnode. */
+   fwnode_for_each_child_node(fwnode, child) {
+   if (fwnode_property_read_u32(child, *props, &val))
+   continue;
+
+   /* Found property, see if its value matches. */
+   if (val == *args)
+   break;
+   }
+
+   fwnode_handle_put(fwnode);
+
+   /* No property found; return an error here. */
+   if (!child) {
+   fwnode = ERR_PTR(-ENOENT);
+   break;
+   }
+
+   props++;
+   args++;
+   fwnode = child;
+   nprops--;
+   }
+
+   return fwnode;
+}
+
+/*
+ * v4l2_fwnode_reference_parse_int_props - parse references for async 
sub-devices
+ * @dev: struct device pointer
+ * @notifier: notifier for @dev
+ * @prop: the name of the property
+ * @props: the array of integer property names
+ * @nprops: the number of integer properties
+ *
+ * Use v4l2_fwnode_reference_get_int_prop to find fwnodes through reference in
+ * property @prop with integer arguments with child nodes matching in 
properties
+ * @props. Then, set up V4L2 async sub-devices for those fwnodes in the 
notifier
+ * accordingly.
+ *
+ * While it is technically possible to use this function on DT, it is only
+ * meaningful on ACPI. On Device tree you can refer to any node in the tree but
+ * on ACPI the references are limited to devices.
+ *
+ * Return: 0 on success
+ *-ENOENT if no entries (or the property itself) were found
+ *-EINVAL if property parsing otherwisefailed
+ *-ENOMEM if memory allocation failed
+ */
+static int v4l2_fwnode_reference_parse_int_props(
+   struct device *dev, struct v4l2_async_notifier *notifier,
+   const char *prop, const char **props, unsigned int nprops)
+{
+   struct fwnode_handle *fwnode;
+   unsigned int index;
+   int ret;
+
+   for (index = 0; !IS_ERR((fwnode = v4l2_fwnode_reference_get_int_prop(
+dev_fwnode(dev), prop, index, props,
+nprops))); index++)
+   fwnode_handle_put(fwnode);
+
+   if (PTR_ERR(fwnode) != -ENOENT)
+   return PTR_ERR(fwnode);
+
+   ret = v4l2_async_notifier_realloc(notifier,
+ notifier->num_subdevs + index);
+   if (ret)
+   return -ENOMEM;
+
+   for (index = 0; !IS_ERR

[PATCH v11 17/24] v4l: fwnode: Add a helper function for parsing generic references

2017-09-12 Thread Sakari Ailus
Add function v4l2_fwnode_reference_count() for counting external
references and v4l2_fwnode_reference_parse() for parsing them as async
sub-devices.

This can be done on e.g. flash or lens async sub-devices that are not part
of but are associated with a sensor.

struct v4l2_async_notifier.max_subdevs field is added to contain the
maximum number of sub-devices in a notifier to reflect the memory
allocated for the subdevs array.

Signed-off-by: Sakari Ailus 
---
 drivers/media/v4l2-core/v4l2-fwnode.c | 69 +++
 1 file changed, 69 insertions(+)

diff --git a/drivers/media/v4l2-core/v4l2-fwnode.c 
b/drivers/media/v4l2-core/v4l2-fwnode.c
index d978f2d714ca..a61c16b337a0 100644
--- a/drivers/media/v4l2-core/v4l2-fwnode.c
+++ b/drivers/media/v4l2-core/v4l2-fwnode.c
@@ -449,6 +449,75 @@ int v4l2_async_notifier_parse_fwnode_endpoints(
 }
 EXPORT_SYMBOL_GPL(v4l2_async_notifier_parse_fwnode_endpoints);
 
+/*
+ * v4l2_fwnode_reference_parse - parse references for async sub-devices
+ * @dev: the device node the properties of which are parsed for references
+ * @notifier: the async notifier where the async subdevs will be added
+ * @prop: the name of the property
+ *
+ * Return: 0 on success
+ *-ENOENT if no entries were found
+ *-ENOMEM if memory allocation failed
+ *-EINVAL if property parsing failed
+ */
+static int v4l2_fwnode_reference_parse(
+   struct device *dev, struct v4l2_async_notifier *notifier,
+   const char *prop)
+{
+   struct fwnode_reference_args args;
+   unsigned int index;
+   int ret;
+
+   for (index = 0;
+!(ret = fwnode_property_get_reference_args(
+  dev_fwnode(dev), prop, NULL, 0, index, &args));
+index++)
+   fwnode_handle_put(args.fwnode);
+
+   if (!index)
+   return -ENOENT;
+
+   /*
+* To-do: handle -ENODATA when "device property: Align return
+* codes of acpi_fwnode_get_reference_with_args" is merged.
+*/
+   if (ret != -ENOENT && ret != -ENODATA)
+   return ret;
+
+   ret = v4l2_async_notifier_realloc(notifier,
+ notifier->num_subdevs + index);
+   if (ret)
+   return ret;
+
+   for (index = 0; !fwnode_property_get_reference_args(
+dev_fwnode(dev), prop, NULL, 0, index, &args);
+index++) {
+   struct v4l2_async_subdev *asd;
+
+   if (WARN_ON(notifier->num_subdevs >= notifier->max_subdevs)) {
+   ret = -EINVAL;
+   goto error;
+   }
+
+   asd = kzalloc(sizeof(*asd), GFP_KERNEL);
+   if (!asd) {
+   ret = -ENOMEM;
+   goto error;
+   }
+
+   notifier->subdevs[notifier->num_subdevs] = asd;
+   asd->match.fwnode.fwnode = args.fwnode;
+   asd->match_type = V4L2_ASYNC_MATCH_FWNODE;
+   notifier->num_subdevs++;
+   }
+
+   return 0;
+
+error:
+   fwnode_handle_put(args.fwnode);
+   return ret;
+}
+
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Sakari Ailus ");
 MODULE_AUTHOR("Sylwester Nawrocki ");
-- 
2.11.0



[PATCH v11 22/24] ov5670: Add support for flash and lens devices

2017-09-12 Thread Sakari Ailus
Parse async sub-devices by using
v4l2_subdev_fwnode_reference_parse_sensor_common().

Signed-off-by: Sakari Ailus 
Acked-by: Hans Verkuil 
---
 drivers/media/i2c/ov5670.c | 33 +
 1 file changed, 25 insertions(+), 8 deletions(-)

diff --git a/drivers/media/i2c/ov5670.c b/drivers/media/i2c/ov5670.c
index 6f7a1d6d2200..25970307dd75 100644
--- a/drivers/media/i2c/ov5670.c
+++ b/drivers/media/i2c/ov5670.c
@@ -18,6 +18,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #define OV5670_REG_CHIP_ID 0x300a
 #define OV5670_CHIP_ID 0x005670
@@ -1807,6 +1808,7 @@ static const struct ov5670_mode supported_modes[] = {
 struct ov5670 {
struct v4l2_subdev sd;
struct media_pad pad;
+   struct v4l2_async_notifier notifier;
 
struct v4l2_ctrl_handler ctrl_handler;
/* V4L2 Controls */
@@ -2473,11 +2475,13 @@ static int ov5670_probe(struct i2c_client *client)
return -EINVAL;
 
ov5670 = devm_kzalloc(&client->dev, sizeof(*ov5670), GFP_KERNEL);
-   if (!ov5670) {
-   ret = -ENOMEM;
-   err_msg = "devm_kzalloc() error";
-   goto error_print;
-   }
+   if (!ov5670)
+   return -ENOMEM;
+
+   ret = v4l2_fwnode_reference_parse_sensor_common(
+   &client->dev, &ov5670->notifier);
+   if (ret < 0)
+   return ret;
 
/* Initialize subdev */
v4l2_i2c_subdev_init(&ov5670->sd, client, &ov5670_subdev_ops);
@@ -2486,7 +2490,7 @@ static int ov5670_probe(struct i2c_client *client)
ret = ov5670_identify_module(ov5670);
if (ret) {
err_msg = "ov5670_identify_module() error";
-   goto error_print;
+   goto error_release_notifier;
}
 
mutex_init(&ov5670->mutex);
@@ -2513,11 +2517,18 @@ static int ov5670_probe(struct i2c_client *client)
goto error_handler_free;
}
 
+   ret = v4l2_async_subdev_notifier_register(&ov5670->sd,
+ &ov5670->notifier);
+   if (ret) {
+   err_msg = "can't register async notifier";
+   goto error_entity_cleanup;
+   }
+
/* Async register for subdev */
ret = v4l2_async_register_subdev(&ov5670->sd);
if (ret < 0) {
err_msg = "v4l2_async_register_subdev() error";
-   goto error_entity_cleanup;
+   goto error_unregister_notifier;
}
 
ov5670->streaming = false;
@@ -2533,6 +2544,9 @@ static int ov5670_probe(struct i2c_client *client)
 
return 0;
 
+error_unregister_notifier:
+   v4l2_async_notifier_unregister(&ov5670->notifier);
+
 error_entity_cleanup:
media_entity_cleanup(&ov5670->sd.entity);
 
@@ -2542,7 +2556,8 @@ static int ov5670_probe(struct i2c_client *client)
 error_mutex_destroy:
mutex_destroy(&ov5670->mutex);
 
-error_print:
+error_release_notifier:
+   v4l2_async_notifier_release(&ov5670->notifier);
dev_err(&client->dev, "%s: %s %d\n", __func__, err_msg, ret);
 
return ret;
@@ -2554,6 +2569,8 @@ static int ov5670_remove(struct i2c_client *client)
struct ov5670 *ov5670 = to_ov5670(sd);
 
v4l2_async_unregister_subdev(sd);
+   v4l2_async_notifier_unregister(&ov5670->notifier);
+   v4l2_async_notifier_release(&ov5670->notifier);
media_entity_cleanup(&sd->entity);
v4l2_ctrl_handler_free(sd->ctrl_handler);
mutex_destroy(&ov5670->mutex);
-- 
2.11.0



[PATCH v11 19/24] v4l: fwnode: Add convenience function for parsing common external refs

2017-09-12 Thread Sakari Ailus
Add v4l2_fwnode_parse_reference_sensor_common for parsing common
sensor properties that refer to adjacent devices such as flash or lens
driver chips.

As this is an association only, there's little a regular driver needs to
know about these devices as such.

Signed-off-by: Sakari Ailus 
Acked-by: Hans Verkuil 
Acked-by: Pavel Machek 
---
 drivers/media/v4l2-core/v4l2-fwnode.c | 35 +++
 include/media/v4l2-async.h|  3 ++-
 include/media/v4l2-fwnode.h   | 21 +
 3 files changed, 58 insertions(+), 1 deletion(-)

diff --git a/drivers/media/v4l2-core/v4l2-fwnode.c 
b/drivers/media/v4l2-core/v4l2-fwnode.c
index 93bd9c29fd43..ffe86ca656f4 100644
--- a/drivers/media/v4l2-core/v4l2-fwnode.c
+++ b/drivers/media/v4l2-core/v4l2-fwnode.c
@@ -663,6 +663,41 @@ static int v4l2_fwnode_reference_parse_int_props(
return ret;
 }
 
+int v4l2_fwnode_reference_parse_sensor_common(
+   struct device *dev, struct v4l2_async_notifier *notifier)
+{
+   static const char *led_props[] = { "led" };
+   static const struct {
+   const char *name;
+   const char **props;
+   unsigned int nprops;
+   } props[] = {
+   { "flash-leds", led_props, ARRAY_SIZE(led_props) },
+   { "lens-focus", NULL, 0 },
+   };
+   unsigned int i;
+
+   for (i = 0; i < ARRAY_SIZE(props); i++) {
+   int ret;
+
+   if (props[i].props && is_acpi_node(dev_fwnode(dev)))
+   ret = v4l2_fwnode_reference_parse_int_props(
+   dev, notifier, props[i].name,
+   props[i].props, props[i].nprops);
+   else
+   ret = v4l2_fwnode_reference_parse(
+   dev, notifier, props[i].name);
+   if (ret && ret != -ENOENT) {
+   dev_warn(dev, "parsing property \"%s\" failed (%d)\n",
+props[i].name, ret);
+   return ret;
+   }
+   }
+
+   return 0;
+}
+EXPORT_SYMBOL_GPL(v4l2_fwnode_reference_parse_sensor_common);
+
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Sakari Ailus ");
 MODULE_AUTHOR("Sylwester Nawrocki ");
diff --git a/include/media/v4l2-async.h b/include/media/v4l2-async.h
index a13803a6371d..378e20e3b44d 100644
--- a/include/media/v4l2-async.h
+++ b/include/media/v4l2-async.h
@@ -155,7 +155,8 @@ void v4l2_async_notifier_unregister(struct 
v4l2_async_notifier *notifier);
  * Release memory resources related to a notifier, including the async
  * sub-devices allocated for the purposes of the notifier. The user is
  * responsible for releasing the notifier's resources after calling
- * @v4l2_async_notifier_parse_fwnode_endpoints.
+ * @v4l2_async_notifier_parse_fwnode_endpoints or
+ * @v4l2_fwnode_reference_parse_sensor_common.
  *
  * There is no harm from calling v4l2_async_notifier_release in other
  * cases as long as its memory has been zeroed after it has been
diff --git a/include/media/v4l2-fwnode.h b/include/media/v4l2-fwnode.h
index 31fb77e470fa..fcea9886a2b6 100644
--- a/include/media/v4l2-fwnode.h
+++ b/include/media/v4l2-fwnode.h
@@ -257,4 +257,25 @@ int v4l2_async_notifier_parse_fwnode_endpoints(
  struct v4l2_fwnode_endpoint *vep,
  struct v4l2_async_subdev *asd));
 
+/**
+ * v4l2_fwnode_reference_parse_sensor_common - parse common references on
+ *sensors for async sub-devices
+ * @dev: the device node the properties of which are parsed for references
+ * @notifier: the async notifier where the async subdevs will be added
+ *
+ * Parse common sensor properties for remote devices related to the
+ * sensor and set up async sub-devices for them.
+ *
+ * Any notifier populated using this function must be released with a call to
+ * v4l2_async_notifier_release() after it has been unregistered and the async
+ * sub-devices are no longer in use, even in the case the function returned an
+ * error.
+ *
+ * Return: 0 on success
+ *-ENOMEM if memory allocation failed
+ *-EINVAL if property parsing failed
+ */
+int v4l2_fwnode_reference_parse_sensor_common(
+   struct device *dev, struct v4l2_async_notifier *notifier);
+
 #endif /* _V4L2_FWNODE_H */
-- 
2.11.0