cron job: media_tree daily build: WARNINGS

2017-10-26 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:   Fri Oct 27 05:00:18 CEST 2017
media-tree git hash:61065fc3e32002ba48aa6bc3816c1f6f9f8daf55
media_build git hash:   c93534951f5d66bef7f17f16293acf2be346b726
v4l-utils git hash: 482c52f946af4c6b16efa63a35790d92fb65326c
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: WARNINGS
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: OK
spec-git: OK

Detailed results are available here:

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

Full logs are available here:

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

The Media Infrastructure API from this daily build is here:

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


[PATCH] media: i2c: Add the ov7740 image sensor driver

2017-10-26 Thread Wenyou Yang
From: Songjun Wu 

The ov7740 (color) image sensor is a high performance VGA CMOS
image snesor, which supports for output formats: RAW RGB and YUV
and image sizes: VGA, and QVGA, CIF and any size smaller.

Signed-off-by: Songjun Wu 
Signed-off-by: Wenyou Yang 
---

 .../devicetree/bindings/media/i2c/ov7740.txt   |   43 +
 drivers/media/i2c/Kconfig  |8 +
 drivers/media/i2c/Makefile |1 +
 drivers/media/i2c/ov7740.c | 1220 
 4 files changed, 1272 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/media/i2c/ov7740.txt
 create mode 100644 drivers/media/i2c/ov7740.c

diff --git a/Documentation/devicetree/bindings/media/i2c/ov7740.txt 
b/Documentation/devicetree/bindings/media/i2c/ov7740.txt
new file mode 100644
index ..b306e5aa97bf
--- /dev/null
+++ b/Documentation/devicetree/bindings/media/i2c/ov7740.txt
@@ -0,0 +1,43 @@
+* Omnivision OV7740 CMOS image sensor
+
+The Omnivision OV7740 image sensor supports multiple output image
+size, such as VGA, and QVGA, CIF and any size smaller. It also
+supports the RAW RGB and YUV output formats.
+
+Required Properties:
+- compatible: should be "ovti,ov7740"
+- clocks: reference to the xvclk input clock.
+- clock-names: should be "xvclk".
+
+Optional Properties:
+- reset-gpios: reference to the GPIO connected to the reset_b pin,
+  if any. Active low with pull-ip resistor.
+- powerdown-gpios: reference to the GPIO connected to the pwdn pin,
+  if any. Active high with pull-down resistor.
+
+The device node must contain one 'port' child node for its digital
+output video port, in accordance with the video interface bindings
+defined in Documentation/devicetree/bindings/media/video-interfaces.txt.
+
+Example:
+
+   i2c1: i2c@fc028000 {
+   ov7740: camera@21 {
+   compatible = "ovti,ov7740";
+   reg = <0x21>;
+   pinctrl-names = "default";
+   pinctrl-0 = <_sensor_power 
_sensor_reset>;
+   clocks = <>;
+   clock-names = "xvclk";
+   assigned-clocks = <>;
+   assigned-clock-rates = <2400>;
+   reset-gpios = < 43 GPIO_ACTIVE_LOW>;
+   powerdown-gpios = < 44 GPIO_ACTIVE_HIGH>;
+
+   port {
+   ov7740_0: endpoint {
+   remote-endpoint = <_0>;
+   };
+   };
+   };
+   };
diff --git a/drivers/media/i2c/Kconfig b/drivers/media/i2c/Kconfig
index 47113774a297..402ad0e4024c 100644
--- a/drivers/media/i2c/Kconfig
+++ b/drivers/media/i2c/Kconfig
@@ -657,6 +657,14 @@ config VIDEO_OV7670
  OV7670 VGA camera.  It currently only works with the M88ALP01
  controller.
 
+config VIDEO_OV7740
+   tristate "OmniVision OV7740 sensor support"
+   depends on I2C && VIDEO_V4L2
+   depends on MEDIA_CAMERA_SUPPORT
+   ---help---
+ This is a Video4Linux2 sensor-level driver for the OmniVision
+ OV7740 VGA camera sensor.
+
 config VIDEO_OV9650
tristate "OmniVision OV9650/OV9652 sensor support"
depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API
diff --git a/drivers/media/i2c/Makefile b/drivers/media/i2c/Makefile
index c843c181dfb9..f94cb2a8ed91 100644
--- a/drivers/media/i2c/Makefile
+++ b/drivers/media/i2c/Makefile
@@ -67,6 +67,7 @@ obj-$(CONFIG_VIDEO_OV5670) += ov5670.o
 obj-$(CONFIG_VIDEO_OV6650) += ov6650.o
 obj-$(CONFIG_VIDEO_OV7640) += ov7640.o
 obj-$(CONFIG_VIDEO_OV7670) += ov7670.o
+obj-$(CONFIG_VIDEO_OV7740) += ov7740.o
 obj-$(CONFIG_VIDEO_OV9650) += ov9650.o
 obj-$(CONFIG_VIDEO_OV13858) += ov13858.o
 obj-$(CONFIG_VIDEO_MT9M032) += mt9m032.o
diff --git a/drivers/media/i2c/ov7740.c b/drivers/media/i2c/ov7740.c
new file mode 100644
index ..d68add05b46e
--- /dev/null
+++ b/drivers/media/i2c/ov7740.c
@@ -0,0 +1,1220 @@
+/*
+ * Copyright (c) 2017 Microchip Corporation.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License version
+ * 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define REG_OUTSIZE_LSB 0x34
+
+/* OV7740 register tables */
+#define REG_GAIN   0x00/* Gain lower 8 bits (rest in vref) */
+#define REG_BGAIN  0x01/* blue gain */
+#define REG_RGAIN  0x02 

[PATCH v5 5/5] media: atmel-isc: Rework the format list

2017-10-26 Thread Wenyou Yang
To improve the readability of code, split the format array into two,
one for the format description, other for the register configuration.
Meanwhile, add the flag member to indicate the format can be achieved
from the sensor or be produced by the controller, and rename members
related to the register configuration.

Also add more formats support: GREY, ARGB444, ARGB555 and ARGB32.

Signed-off-by: Wenyou Yang 
---

Changes in v5: None
Changes in v4: None
Changes in v3:
 - Add a new flag for Raw Bayer format to remove MAX_RAW_FMT_INDEX define.
 - Add the comments for define of the format flag.
 - Rebase media_tree/master.

Changes in v2:
 - Add the new patch to remove the unnecessary member from
   isc_subdev_entity struct.
 - Rebase on the patch set,
[PATCH 0/6] [media] Atmel: Adjustments for seven function 
implementations
https://www.mail-archive.com/linux-media@vger.kernel.org/msg118342.html

 drivers/media/platform/atmel/atmel-isc.c | 530 ---
 1 file changed, 411 insertions(+), 119 deletions(-)

diff --git a/drivers/media/platform/atmel/atmel-isc.c 
b/drivers/media/platform/atmel/atmel-isc.c
index a99796f7eb03..9294ff0c7b83 100644
--- a/drivers/media/platform/atmel/atmel-isc.c
+++ b/drivers/media/platform/atmel/atmel-isc.c
@@ -89,34 +89,63 @@ struct isc_subdev_entity {
struct list_head list;
 };
 
+/* Indicate the format is generated by the sensor */
+#define FMT_FLAG_FROM_SENSOR   BIT(0)
+/* Indicate the format is produced by ISC itself */
+#define FMT_FLAG_FROM_CONTROLLER   BIT(1)
+/* Indicate a Raw Bayer format */
+#define FMT_FLAG_RAW_FORMATBIT(2)
+
+#define FMT_FLAG_RAW_FROM_SENSOR   (FMT_FLAG_FROM_SENSOR | \
+FMT_FLAG_RAW_FORMAT)
+
 /*
  * struct isc_format - ISC media bus format information
  * @fourcc:Fourcc code for this format
  * @mbus_code: V4L2 media bus format code.
+ * flags:  Indicate format from sensor or converted by controller
  * @bpp:   Bits per pixel (when stored in memory)
- * @reg_bps:   reg value for bits per sample
  * (when transferred over a bus)
- * @pipeline:  pipeline switch
  * @sd_support:Subdev supports this format
  * @isc_support:   ISC can convert raw format to this format
  */
+
 struct isc_format {
u32 fourcc;
u32 mbus_code;
+   u32 flags;
u8  bpp;
 
-   u32 reg_bps;
-   u32 reg_bay_cfg;
-   u32 reg_rlp_mode;
-   u32 reg_dcfg_imode;
-   u32 reg_dctrl_dview;
-
-   u32 pipeline;
-
boolsd_support;
boolisc_support;
 };
 
+/* Pipeline bitmap */
+#define WB_ENABLE  BIT(0)
+#define CFA_ENABLE BIT(1)
+#define CC_ENABLE  BIT(2)
+#define GAM_ENABLE BIT(3)
+#define GAM_BENABLEBIT(4)
+#define GAM_GENABLEBIT(5)
+#define GAM_RENABLEBIT(6)
+#define CSC_ENABLE BIT(7)
+#define CBC_ENABLE BIT(8)
+#define SUB422_ENABLE  BIT(9)
+#define SUB420_ENABLE  BIT(10)
+
+#define GAM_ENABLES(GAM_RENABLE | GAM_GENABLE | GAM_BENABLE | GAM_ENABLE)
+
+struct fmt_config {
+   u32 fourcc;
+
+   u32 pfe_cfg0_bps;
+   u32 cfa_baycfg;
+   u32 rlp_cfg_mode;
+   u32 dcfg_imode;
+   u32 dctrl_dview;
+
+   u32 bits_pipeline;
+};
 
 #define HIST_ENTRIES   512
 #define HIST_BAYER (ISC_HIS_CFG_MODE_B + 1)
@@ -181,80 +210,320 @@ struct isc_device {
struct list_headsubdev_entities;
 };
 
-#define RAW_FMT_IND_START0
-#define RAW_FMT_IND_END  11
-#define ISC_FMT_IND_START12
-#define ISC_FMT_IND_END  14
-
-static struct isc_format isc_formats[] = {
-   { V4L2_PIX_FMT_SBGGR8, MEDIA_BUS_FMT_SBGGR8_1X8, 8,
- ISC_PFE_CFG0_BPS_EIGHT, ISC_BAY_CFG_BGBG, ISC_RLP_CFG_MODE_DAT8,
- ISC_DCFG_IMODE_PACKED8, ISC_DCTRL_DVIEW_PACKED, 0x0,
- false, false },
-   { V4L2_PIX_FMT_SGBRG8, MEDIA_BUS_FMT_SGBRG8_1X8, 8,
- ISC_PFE_CFG0_BPS_EIGHT, ISC_BAY_CFG_GBGB, ISC_RLP_CFG_MODE_DAT8,
- ISC_DCFG_IMODE_PACKED8, ISC_DCTRL_DVIEW_PACKED, 0x0,
- false, false },
-   { V4L2_PIX_FMT_SGRBG8, MEDIA_BUS_FMT_SGRBG8_1X8, 8,
- ISC_PFE_CFG0_BPS_EIGHT, ISC_BAY_CFG_GRGR, ISC_RLP_CFG_MODE_DAT8,
- ISC_DCFG_IMODE_PACKED8, ISC_DCTRL_DVIEW_PACKED, 0x0,
- false, false },
-   { V4L2_PIX_FMT_SRGGB8, MEDIA_BUS_FMT_SRGGB8_1X8, 8,
- ISC_PFE_CFG0_BPS_EIGHT, ISC_BAY_CFG_RGRG, ISC_RLP_CFG_MODE_DAT8,
- ISC_DCFG_IMODE_PACKED8, ISC_DCTRL_DVIEW_PACKED, 0x0,
- false, false },
-
-   { V4L2_PIX_FMT_SBGGR10, MEDIA_BUS_FMT_SBGGR10_1X10, 16,
- ISC_PFG_CFG0_BPS_TEN, ISC_BAY_CFG_BGBG, ISC_RLP_CFG_MODE_DAT10,
- ISC_DCFG_IMODE_PACKED16, ISC_DCTRL_DVIEW_PACKED, 0x0,
- false, false },
-   { V4L2_PIX_FMT_SGBRG10, 

[PATCH v5 1/5] media: atmel-isc: Add spin lock for clock enable ops

2017-10-26 Thread Wenyou Yang
Add the spin lock for the clock enable and disable operations.

Signed-off-by: Wenyou Yang 
---

Changes in v5: None
Changes in v4: None
Changes in v3:
 - Fix the wrong used spinlock.
 - s/_/- on the subject.

Changes in v2: None

 drivers/media/platform/atmel/atmel-isc.c | 15 ++-
 1 file changed, 14 insertions(+), 1 deletion(-)

diff --git a/drivers/media/platform/atmel/atmel-isc.c 
b/drivers/media/platform/atmel/atmel-isc.c
index 2f8e345d297e..991f962b7023 100644
--- a/drivers/media/platform/atmel/atmel-isc.c
+++ b/drivers/media/platform/atmel/atmel-isc.c
@@ -65,6 +65,7 @@ struct isc_clk {
struct clk_hw   hw;
struct clk  *clk;
struct regmap   *regmap;
+   spinlock_t  lock;
u8  id;
u8  parent_id;
u32 div;
@@ -312,26 +313,37 @@ static int isc_clk_enable(struct clk_hw *hw)
struct isc_clk *isc_clk = to_isc_clk(hw);
u32 id = isc_clk->id;
struct regmap *regmap = isc_clk->regmap;
+   unsigned long flags;
+   unsigned int status;
 
dev_dbg(isc_clk->dev, "ISC CLK: %s, div = %d, parent id = %d\n",
__func__, isc_clk->div, isc_clk->parent_id);
 
+   spin_lock_irqsave(_clk->lock, flags);
regmap_update_bits(regmap, ISC_CLKCFG,
   ISC_CLKCFG_DIV_MASK(id) | ISC_CLKCFG_SEL_MASK(id),
   (isc_clk->div << ISC_CLKCFG_DIV_SHIFT(id)) |
   (isc_clk->parent_id << ISC_CLKCFG_SEL_SHIFT(id)));
 
regmap_write(regmap, ISC_CLKEN, ISC_CLK(id));
+   spin_unlock_irqrestore(_clk->lock, flags);
 
-   return 0;
+   regmap_read(regmap, ISC_CLKSR, );
+   if (status & ISC_CLK(id))
+   return 0;
+   else
+   return -EINVAL;
 }
 
 static void isc_clk_disable(struct clk_hw *hw)
 {
struct isc_clk *isc_clk = to_isc_clk(hw);
u32 id = isc_clk->id;
+   unsigned long flags;
 
+   spin_lock_irqsave(_clk->lock, flags);
regmap_write(isc_clk->regmap, ISC_CLKDIS, ISC_CLK(id));
+   spin_unlock_irqrestore(_clk->lock, flags);
 }
 
 static int isc_clk_is_enabled(struct clk_hw *hw)
@@ -492,6 +504,7 @@ static int isc_clk_register(struct isc_device *isc, 
unsigned int id)
isc_clk->regmap = regmap;
isc_clk->id = id;
isc_clk->dev= isc->dev;
+   spin_lock_init(_clk->lock);
 
isc_clk->clk = clk_register(isc->dev, _clk->hw);
if (IS_ERR(isc_clk->clk)) {
-- 
2.13.0



[PATCH v5 0/5] media: atmel-isc: Rework the format list and clock provider

2017-10-26 Thread Wenyou Yang
To improve the readability of code, rework the format list table,
split the format array into two. Meanwhile, fix the issue of the
clock provider operation and the pm runtime support.

Changes in v5:
 - Fix the clock ID which enters the runtime suspend should be
   ISC_ISPCK, instead of ISC_MCK for clk_prepare/clk_unprepare().
 - Fix the clock ID to ISC_ISPCK, instead of ISC_MCK for
   isc_clk_is_enabled().

Changes in v4:
 - Call pm_runtime_get_sync() and pm_runtime_put_sync() in ->prepare
   and ->unprepare callback.
 - Move pm_runtime_enable() call from the complete callback to the
   end of probe.
 - Call pm_runtime_get_sync() and pm_runtime_put_sync() in
   ->is_enabled() callbacks.
 - Call clk_disable_unprepare() in ->remove callback.

Changes in v3:
 - Fix the wrong used spinlock.
 - s/_/- on the subject.
 - Add a new flag for Raw Bayer format to remove MAX_RAW_FMT_INDEX define.
 - Add the comments for define of the format flag.
 - Rebase media_tree/master.

Changes in v2:
 - Add the new patch to remove the unnecessary member from
   isc_subdev_entity struct.
 - Rebase on the patch set,
[PATCH 0/6] [media] Atmel: Adjustments for seven function 
implementations
https://www.mail-archive.com/linux-media@vger.kernel.org/msg118342.html

Wenyou Yang (5):
  media: atmel-isc: Add spin lock for clock enable ops
  media: atmel-isc: Add prepare and unprepare ops
  media: atmel-isc: Enable the clocks during probe
  media: atmel-isc: Remove unnecessary member
  media: atmel-isc: Rework the format list

 drivers/media/platform/atmel/atmel-isc-regs.h |   1 +
 drivers/media/platform/atmel/atmel-isc.c  | 629 --
 2 files changed, 498 insertions(+), 132 deletions(-)

-- 
2.13.0



[PATCH v5 4/5] media: atmel-isc: Remove unnecessary member

2017-10-26 Thread Wenyou Yang
Remove the memeber *config from the isc_subdev_entity struct,
the member is useless afterward.

Signed-off-by: Wenyou Yang 
---

Changes in v5: None
Changes in v4: None
Changes in v3: None
Changes in v2: None

 drivers/media/platform/atmel/atmel-isc.c | 10 ++
 1 file changed, 2 insertions(+), 8 deletions(-)

diff --git a/drivers/media/platform/atmel/atmel-isc.c 
b/drivers/media/platform/atmel/atmel-isc.c
index 4431c27dfb09..a99796f7eb03 100644
--- a/drivers/media/platform/atmel/atmel-isc.c
+++ b/drivers/media/platform/atmel/atmel-isc.c
@@ -83,7 +83,6 @@ struct isc_subdev_entity {
struct v4l2_subdev  *sd;
struct v4l2_async_subdev*asd;
struct v4l2_async_notifier  notifier;
-   struct v4l2_subdev_pad_config   *config;
 
u32 pfe_cfg0;
 
@@ -1000,6 +999,7 @@ static int isc_try_fmt(struct isc_device *isc, struct 
v4l2_format *f,
 {
struct isc_format *isc_fmt;
struct v4l2_pix_format *pixfmt = >fmt.pix;
+   struct v4l2_subdev_pad_config pad_cfg;
struct v4l2_subdev_format format = {
.which = V4L2_SUBDEV_FORMAT_TRY,
};
@@ -1030,7 +1030,7 @@ static int isc_try_fmt(struct isc_device *isc, struct 
v4l2_format *f,
 
v4l2_fill_mbus_format(, pixfmt, mbus_code);
ret = v4l2_subdev_call(isc->current_subdev->sd, pad, set_fmt,
-  isc->current_subdev->config, );
+  _cfg, );
if (ret < 0)
return ret;
 
@@ -1495,8 +1495,6 @@ static void isc_async_unbind(struct v4l2_async_notifier 
*notifier,
  struct isc_device, v4l2_dev);
cancel_work_sync(>awb_work);
video_unregister_device(>video_dev);
-   if (isc->current_subdev->config)
-   v4l2_subdev_free_pad_config(isc->current_subdev->config);
v4l2_ctrl_handler_free(>ctrls.handler);
 }
 
@@ -1648,10 +1646,6 @@ static int isc_async_complete(struct v4l2_async_notifier 
*notifier)
INIT_LIST_HEAD(>dma_queue);
spin_lock_init(>dma_queue_lock);
 
-   sd_entity->config = v4l2_subdev_alloc_pad_config(sd_entity->sd);
-   if (!sd_entity->config)
-   return -ENOMEM;
-
ret = isc_formats_init(isc);
if (ret < 0) {
v4l2_err(>v4l2_dev,
-- 
2.13.0



[PATCH v5 2/5] media: atmel-isc: Add prepare and unprepare ops

2017-10-26 Thread Wenyou Yang
A software write operation to the ISC_CLKEN or ISC_CLKDIS register
requires double clock domain synchronization and is not permitted
when the ISC_SR.SIP is asserted. So add the .prepare and .unprepare
ops to make sure the ISC_CLKSR.SIP is unasserted before the write
operation to the ISC_CLKEN or ISC_CLKDIS register.

Signed-off-by: Wenyou Yang 
---

Changes in v5:
 - Fix the clock ID which enters the runtime suspend should be
   ISC_ISPCK, instead of ISC_MCK for clk_prepare/clk_unprepare().

Changes in v4:
 - Call pm_runtime_get_sync() and pm_runtime_put_sync() in ->prepare
   and ->unprepare callback.

Changes in v3: None
Changes in v2: None

 drivers/media/platform/atmel/atmel-isc-regs.h |  1 +
 drivers/media/platform/atmel/atmel-isc.c  | 40 +++
 2 files changed, 41 insertions(+)

diff --git a/drivers/media/platform/atmel/atmel-isc-regs.h 
b/drivers/media/platform/atmel/atmel-isc-regs.h
index 6936ac467609..93e58fcf1d5f 100644
--- a/drivers/media/platform/atmel/atmel-isc-regs.h
+++ b/drivers/media/platform/atmel/atmel-isc-regs.h
@@ -42,6 +42,7 @@
 
 /* ISC Clock Status Register */
 #define ISC_CLKSR   0x0020
+#define ISC_CLKSR_SIP  BIT(31)
 
 #define ISC_CLK(n) BIT(n)
 
diff --git a/drivers/media/platform/atmel/atmel-isc.c 
b/drivers/media/platform/atmel/atmel-isc.c
index 991f962b7023..329ee8f256bb 100644
--- a/drivers/media/platform/atmel/atmel-isc.c
+++ b/drivers/media/platform/atmel/atmel-isc.c
@@ -308,6 +308,44 @@ module_param(sensor_preferred, uint, 0644);
 MODULE_PARM_DESC(sensor_preferred,
 "Sensor is preferred to output the specified format (1-on 
0-off), default 1");
 
+static int isc_wait_clk_stable(struct clk_hw *hw)
+{
+   struct isc_clk *isc_clk = to_isc_clk(hw);
+   struct regmap *regmap = isc_clk->regmap;
+   unsigned long timeout = jiffies + usecs_to_jiffies(1000);
+   unsigned int status;
+
+   while (time_before(jiffies, timeout)) {
+   regmap_read(regmap, ISC_CLKSR, );
+   if (!(status & ISC_CLKSR_SIP))
+   return 0;
+
+   usleep_range(10, 250);
+   }
+
+   return -ETIMEDOUT;
+}
+
+static int isc_clk_prepare(struct clk_hw *hw)
+{
+   struct isc_clk *isc_clk = to_isc_clk(hw);
+
+   if (isc_clk->id == ISC_ISPCK)
+   pm_runtime_get_sync(isc_clk->dev);
+
+   return isc_wait_clk_stable(hw);
+}
+
+static void isc_clk_unprepare(struct clk_hw *hw)
+{
+   struct isc_clk *isc_clk = to_isc_clk(hw);
+
+   isc_wait_clk_stable(hw);
+
+   if (isc_clk->id == ISC_ISPCK)
+   pm_runtime_put_sync(isc_clk->dev);
+}
+
 static int isc_clk_enable(struct clk_hw *hw)
 {
struct isc_clk *isc_clk = to_isc_clk(hw);
@@ -459,6 +497,8 @@ static int isc_clk_set_rate(struct clk_hw *hw,
 }
 
 static const struct clk_ops isc_clk_ops = {
+   .prepare= isc_clk_prepare,
+   .unprepare  = isc_clk_unprepare,
.enable = isc_clk_enable,
.disable= isc_clk_disable,
.is_enabled = isc_clk_is_enabled,
-- 
2.13.0



[PATCH v5 3/5] media: atmel-isc: Enable the clocks during probe

2017-10-26 Thread Wenyou Yang
To meet the relationship, enable the HCLOCK and ispck during the
device probe, "isc_pck frequency is less than or equal to isc_ispck,
and isc_ispck is greater than or equal to HCLOCK."
Meanwhile, call the pm_runtime_enable() in the right place.

Signed-off-by: Wenyou Yang 
---

Changes in v5:
 - Fix the clock ID to ISC_ISPCK, instead of ISC_MCK for
   isc_clk_is_enabled().

Changes in v4:
 - Move pm_runtime_enable() call from the complete callback to the
   end of probe.
 - Call pm_runtime_get_sync() and pm_runtime_put_sync() in
   ->is_enabled() callbacks.
 - Call clk_disable_unprepare() in ->remove callback.

Changes in v3: None
Changes in v2: None

 drivers/media/platform/atmel/atmel-isc.c | 34 
 1 file changed, 30 insertions(+), 4 deletions(-)

diff --git a/drivers/media/platform/atmel/atmel-isc.c 
b/drivers/media/platform/atmel/atmel-isc.c
index 329ee8f256bb..4431c27dfb09 100644
--- a/drivers/media/platform/atmel/atmel-isc.c
+++ b/drivers/media/platform/atmel/atmel-isc.c
@@ -389,8 +389,14 @@ static int isc_clk_is_enabled(struct clk_hw *hw)
struct isc_clk *isc_clk = to_isc_clk(hw);
u32 status;
 
+   if (isc_clk->id == ISC_ISPCK)
+   pm_runtime_get_sync(isc_clk->dev);
+
regmap_read(isc_clk->regmap, ISC_CLKSR, );
 
+   if (isc_clk->id == ISC_ISPCK)
+   pm_runtime_put_sync(isc_clk->dev);
+
return status & ISC_CLK(isc_clk->id) ? 1 : 0;
 }
 
@@ -1866,25 +1872,37 @@ static int atmel_isc_probe(struct platform_device *pdev)
return ret;
}
 
+   ret = clk_prepare_enable(isc->hclock);
+   if (ret) {
+   dev_err(dev, "failed to enable hclock: %d\n", ret);
+   return ret;
+   }
+
ret = isc_clk_init(isc);
if (ret) {
dev_err(dev, "failed to init isc clock: %d\n", ret);
-   goto clean_isc_clk;
+   goto unprepare_hclk;
}
 
isc->ispck = isc->isc_clks[ISC_ISPCK].clk;
 
+   ret = clk_prepare_enable(isc->ispck);
+   if (ret) {
+   dev_err(dev, "failed to enable ispck: %d\n", ret);
+   goto unprepare_hclk;
+   }
+
/* ispck should be greater or equal to hclock */
ret = clk_set_rate(isc->ispck, clk_get_rate(isc->hclock));
if (ret) {
dev_err(dev, "failed to set ispck rate: %d\n", ret);
-   goto clean_isc_clk;
+   goto unprepare_clk;
}
 
ret = v4l2_device_register(dev, >v4l2_dev);
if (ret) {
dev_err(dev, "unable to register v4l2 device.\n");
-   goto clean_isc_clk;
+   goto unprepare_clk;
}
 
ret = isc_parse_dt(dev, isc);
@@ -1917,7 +1935,9 @@ static int atmel_isc_probe(struct platform_device *pdev)
break;
}
 
+   pm_runtime_set_active(dev);
pm_runtime_enable(dev);
+   pm_request_idle(dev);
 
return 0;
 
@@ -1927,7 +1947,11 @@ static int atmel_isc_probe(struct platform_device *pdev)
 unregister_v4l2_device:
v4l2_device_unregister(>v4l2_dev);
 
-clean_isc_clk:
+unprepare_clk:
+   clk_disable_unprepare(isc->ispck);
+unprepare_hclk:
+   clk_disable_unprepare(isc->hclock);
+
isc_clk_cleanup(isc);
 
return ret;
@@ -1938,6 +1962,8 @@ static int atmel_isc_remove(struct platform_device *pdev)
struct isc_device *isc = platform_get_drvdata(pdev);
 
pm_runtime_disable(>dev);
+   clk_disable_unprepare(isc->ispck);
+   clk_disable_unprepare(isc->hclock);
 
isc_subdev_cleanup(isc);
 
-- 
2.13.0



Re: [PATCH v4 2/5] media: dt: bindings: Add binding for NVIDIA Tegra Video Decoder Engine

2017-10-26 Thread Rob Herring
On Fri, Oct 20, 2017 at 12:34:22AM +0300, Dmitry Osipenko wrote:
> Add binding documentation for the Video Decoder Engine which is found
> on NVIDIA Tegra20/30/114/124/132 SoC's.
> 
> Signed-off-by: Dmitry Osipenko 
> ---
>  .../devicetree/bindings/media/nvidia,tegra-vde.txt | 55 
> ++
>  1 file changed, 55 insertions(+)
>  create mode 100644 
> Documentation/devicetree/bindings/media/nvidia,tegra-vde.txt

Acked-by: Rob Herring 


Re: [PATCH v16 17/32] v4l: async: Prepare for async sub-device notifiers

2017-10-26 Thread Niklas Söderlund
On 2017-10-26 10:53:27 +0300, Sakari Ailus wrote:
> Refactor the V4L2 async framework a little in preparation for async
> sub-device notifiers. This avoids making some structural changes in the
> patch actually implementing sub-device notifiers, making that patch easier
> to review.
> 
> Signed-off-by: Sakari Ailus 
> Acked-by: Hans Verkuil 

Acked-by: Niklas Söderlund 

> ---
>  drivers/media/v4l2-core/v4l2-async.c | 71 
> ++--
>  1 file changed, 52 insertions(+), 19 deletions(-)
> 
> diff --git a/drivers/media/v4l2-core/v4l2-async.c 
> b/drivers/media/v4l2-core/v4l2-async.c
> index 1b536d68cedf..eb31d96254d1 100644
> --- a/drivers/media/v4l2-core/v4l2-async.c
> +++ b/drivers/media/v4l2-core/v4l2-async.c
> @@ -125,12 +125,13 @@ static struct v4l2_async_subdev *v4l2_async_find_match(
>  }
>  
>  static int v4l2_async_match_notify(struct v4l2_async_notifier *notifier,
> +struct v4l2_device *v4l2_dev,
>  struct v4l2_subdev *sd,
>  struct v4l2_async_subdev *asd)
>  {
>   int ret;
>  
> - ret = v4l2_device_register_subdev(notifier->v4l2_dev, sd);
> + ret = v4l2_device_register_subdev(v4l2_dev, sd);
>   if (ret < 0)
>   return ret;
>  
> @@ -151,6 +152,31 @@ static int v4l2_async_match_notify(struct 
> v4l2_async_notifier *notifier,
>   return 0;
>  }
>  
> +/* 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_device *v4l2_dev = notifier->v4l2_dev;
> + struct v4l2_subdev *sd, *tmp;
> +
> + list_for_each_entry_safe(sd, tmp, _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, v4l2_dev, sd, asd);
> + if (ret < 0) {
> + mutex_unlock(_lock);
> + return ret;
> + }
> + }
> +
> + return 0;
> +}
> +
>  static void v4l2_async_cleanup(struct v4l2_subdev *sd)
>  {
>   v4l2_device_unregister_subdev(sd);
> @@ -172,18 +198,15 @@ static void v4l2_async_notifier_unbind_all_subdevs(
>   }
>  }
>  
> -int v4l2_async_notifier_register(struct v4l2_device *v4l2_dev,
> -  struct v4l2_async_notifier *notifier)
> +static int __v4l2_async_notifier_register(struct v4l2_async_notifier 
> *notifier)
>  {
> - struct v4l2_subdev *sd, *tmp;
>   struct v4l2_async_subdev *asd;
>   int ret;
>   int i;
>  
> - if (!v4l2_dev || notifier->num_subdevs > V4L2_MAX_SUBDEVS)
> + if (notifier->num_subdevs > V4L2_MAX_SUBDEVS)
>   return -EINVAL;
>  
> - notifier->v4l2_dev = v4l2_dev;
>   INIT_LIST_HEAD(>waiting);
>   INIT_LIST_HEAD(>done);
>  
> @@ -216,18 +239,10 @@ int v4l2_async_notifier_register(struct v4l2_device 
> *v4l2_dev,
>  
>   mutex_lock(_lock);
>  
> - list_for_each_entry_safe(sd, tmp, _list, async_list) {
> - int ret;
> -
> - asd = v4l2_async_find_match(notifier, sd);
> - if (!asd)
> - continue;
> -
> - ret = v4l2_async_match_notify(notifier, sd, asd);
> - if (ret < 0) {
> - mutex_unlock(_lock);
> - return ret;
> - }
> + ret = v4l2_async_notifier_try_all_subdevs(notifier);
> + if (ret) {
> + mutex_unlock(_lock);
> + return ret;
>   }
>  
>   if (list_empty(>waiting)) {
> @@ -250,6 +265,23 @@ int v4l2_async_notifier_register(struct v4l2_device 
> *v4l2_dev,
>  
>   return ret;
>  }
> +
> +int v4l2_async_notifier_register(struct v4l2_device *v4l2_dev,
> +  struct v4l2_async_notifier *notifier)
> +{
> + int ret;
> +
> + if (WARN_ON(!v4l2_dev))
> + return -EINVAL;
> +
> + notifier->v4l2_dev = v4l2_dev;
> +
> + ret = __v4l2_async_notifier_register(notifier);
> + if (ret)
> + notifier->v4l2_dev = NULL;
> +
> + return ret;
> +}
>  EXPORT_SYMBOL(v4l2_async_notifier_register);
>  
>  void v4l2_async_notifier_unregister(struct v4l2_async_notifier *notifier)
> @@ -324,7 +356,8 @@ int v4l2_async_register_subdev(struct v4l2_subdev *sd)
>   if (!asd)
>   continue;
>  
> - ret = v4l2_async_match_notify(notifier, sd, asd);
> + ret = v4l2_async_match_notify(notifier, notifier->v4l2_dev, sd,
> +   asd);
>   if (ret)
>   goto err_unlock;
>  
> -- 
> 2.11.0
> 

-- 
Regards,
Niklas Söderlund


Re: [PATCH v16 16/32] v4l: async: Allow async notifier register call succeed with no subdevs

2017-10-26 Thread Niklas Söderlund
On 2017-10-26 10:53:26 +0300, 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 

Acked-by: Niklas Söderlund 

> ---
>  drivers/media/v4l2-core/v4l2-async.c | 12 ++--
>  1 file changed, 10 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/media/v4l2-core/v4l2-async.c 
> b/drivers/media/v4l2-core/v4l2-async.c
> index 46db85685894..1b536d68cedf 100644
> --- a/drivers/media/v4l2-core/v4l2-async.c
> +++ b/drivers/media/v4l2-core/v4l2-async.c
> @@ -180,14 +180,22 @@ int v4l2_async_notifier_register(struct v4l2_device 
> *v4l2_dev,
>   int ret;
>   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(>waiting);
>   INIT_LIST_HEAD(>done);
>  
> + if (!notifier->num_subdevs) {
> + int ret;
> +
> + ret = v4l2_async_notifier_call_complete(notifier);
> + notifier->v4l2_dev = NULL;
> +
> + return ret;
> + }
> +
>   for (i = 0; i < notifier->num_subdevs; i++) {
>   asd = notifier->subdevs[i];
>  
> -- 
> 2.11.0
> 

-- 
Regards,
Niklas Söderlund


Re: [PATCH v16 15/32] v4l: async: Register sub-devices before calling bound callback

2017-10-26 Thread Niklas Söderlund
On 2017-10-26 10:53:25 +0300, Sakari Ailus wrote:
> 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 
> Acked-by: Pavel Machek 

Acked-by: Niklas Söderlund 

> ---
>  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 e170682dae78..46db85685894 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
> 

-- 
Regards,
Niklas Söderlund


Re: [PATCH v16 14/32] v4l: async: Introduce helpers for calling async ops callbacks

2017-10-26 Thread Niklas Söderlund
On 2017-10-26 10:53:24 +0300, 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 
> Acked-by: Hans Verkuil 
> Acked-by: Pavel Machek 

Acked-by: Niklas Söderlund 

> ---
>  drivers/media/v4l2-core/v4l2-async.c | 56 
> +---
>  1 file changed, 39 insertions(+), 17 deletions(-)
> 
> diff --git a/drivers/media/v4l2-core/v4l2-async.c 
> b/drivers/media/v4l2-core/v4l2-async.c
> index 9d6fc5f25619..e170682dae78 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;
>   }
>  
> @@ -140,8 +165,7 @@ static void v4l2_async_notifier_unbind_all_subdevs(
>   struct v4l2_subdev *sd, *tmp;
>  
>   list_for_each_entry_safe(sd, tmp, >done, async_list) {
> - if (notifier->ops->unbind)
> - notifier->ops->unbind(notifier, sd, sd->asd);
> + v4l2_async_notifier_call_unbind(notifier, sd, sd->asd);
>   v4l2_async_cleanup(sd);
>  
>   list_move(>async_list, _list);
> @@ -198,8 +222,8 @@ int v4l2_async_notifier_register(struct v4l2_device 
> *v4l2_dev,
>   }
>   }
>  
> - if (list_empty(>waiting) && notifier->ops->complete) {
> - ret = notifier->ops->complete(notifier);
> + if (list_empty(>waiting)) {
> + ret = v4l2_async_notifier_call_complete(notifier);
>   if (ret)
>   goto err_complete;
>   }
> @@ -296,10 +320,10 @@ int v4l2_async_register_subdev(struct v4l2_subdev *sd)
>   if (ret)
>   goto err_unlock;
>  
> - if (!list_empty(>waiting) || !notifier->ops->complete)
> + if (!list_empty(>waiting))
>   goto out_unlock;
>  
> - ret = notifier->ops->complete(notifier);
> + ret = v4l2_async_notifier_call_complete(notifier);
>   if (ret)
>   goto err_cleanup;
>  
> @@ -315,8 +339,7 @@ int v4l2_async_register_subdev(struct v4l2_subdev *sd)
>   return 0;
>  
>  err_cleanup:
> - if (notifier->ops->unbind)
> - notifier->ops->unbind(notifier, sd, sd->asd);
> + v4l2_async_notifier_call_unbind(notifier, sd, sd->asd);
>   v4l2_async_cleanup(sd);
>  
>  err_unlock:
> @@ -335,8 +358,7 @@ void v4l2_async_unregister_subdev(struct v4l2_subdev *sd)
>  
>   list_add(>asd->list, >waiting);
>  
> - if (notifier->ops->unbind)
> - notifier->ops->unbind(notifier, sd, sd->asd);
> + v4l2_async_notifier_call_unbind(notifier, sd, sd->asd);
>   }
>  
>   v4l2_async_cleanup(sd);
> -- 
> 2.11.0
> 

-- 
Regards,
Niklas Söderlund


Re: [PATCH v16 13/32] v4l: async: Move async subdev notifier operations to a separate structure

2017-10-26 Thread Niklas Söderlund
On 2017-10-26 10:53:23 +0300, Sakari Ailus wrote:
> 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 

Acked-by: Niklas Söderlund 

> ---
>  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   | 30 
> --
>  drivers/staging/media/imx/imx-media-dev.c  |  8 +--
>  include/media/v4l2-async.h | 29 -
>  18 files changed, 135 insertions(+), 66 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 = _async_ops;
>   ret = v4l2_async_notifier_register(>v4l2_dev,
>   >notifier);
>   if (ret) {
> diff --git a/drivers/media/platform/atmel/atmel-isc.c 
> b/drivers/media/platform/atmel/atmel-isc.c
> index 2f8e345d297e..382fe355e616 100644
> --- a/drivers/media/platform/atmel/atmel-isc.c
> +++ b/drivers/media/platform/atmel/atmel-isc.c
> @@ -1637,6 +1637,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;
> @@ -1849,9 +1855,7 @@ static int atmel_isc_probe(struct platform_device *pdev)
>   list_for_each_entry(subdev_entity, >subdev_entities, list) {
>   subdev_entity->notifier.subdevs = _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 = _async_ops;
>  
>   ret = v4l2_async_notifier_register(>v4l2_dev,
>  _entity->notifier);
> diff --git a/drivers/media/platform/atmel/atmel-isi.c 
> b/drivers/media/platform/atmel/atmel-isi.c
> index 463c0146915e..e900995143a3 100644
> --- a/drivers/media/platform/atmel/atmel-isi.c
> +++ b/drivers/media/platform/atmel/atmel-isi.c
> @@ -1103,6 +1103,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,
> +};
> 

Re: [PATCH v16 08/32] v4l: fwnode: Support generic parsing of graph endpoints in a device

2017-10-26 Thread Niklas Söderlund
On 2017-10-26 10:53:18 +0300, Sakari Ailus wrote:
> Add two functions for parsing devices graph endpoints:
> v4l2_async_notifier_parse_fwnode_endpoints and
> v4l2_async_notifier_parse_fwnode_endpoints_by_port. The former iterates
> over all endpoints whereas the latter only iterates over the endpoints in
> a given port.
> 
> The former is mostly useful for existing drivers that currently implement
> the iteration over all the endpoints themselves whereas the latter is
> especially intended for devices with both sinks and sources: async
> sub-devices for external devices connected to the device's sources will
> have already been set up, or the external sub-devices are part of the
> master device.
> 
> Depends-on: ("device property: preserve usecount for node passed to 
> of_fwnode_graph_get_port_parent()")
> Signed-off-by: Sakari Ailus 
> Acked-by: Hans Verkuil 

Acked-by: Niklas Söderlund 

> ---
>  drivers/media/v4l2-core/v4l2-async.c  |  31 ++
>  drivers/media/v4l2-core/v4l2-fwnode.c | 196 
> ++
>  include/media/v4l2-async.h|  24 -
>  include/media/v4l2-fwnode.h   | 118 
>  4 files changed, 367 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/media/v4l2-core/v4l2-async.c 
> b/drivers/media/v4l2-core/v4l2-async.c
> index 8b84fea50c2a..46aebfc75e43 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)
> @@ -237,6 +238,36 @@ void v4l2_async_notifier_unregister(struct 
> v4l2_async_notifier *notifier)
>  }
>  EXPORT_SYMBOL(v4l2_async_notifier_unregister);
>  
> +void v4l2_async_notifier_cleanup(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(true);
> + break;
> + }
> +
> + kfree(asd);
> + }
> +
> + notifier->max_subdevs = 0;
> + notifier->num_subdevs = 0;
> +
> + kvfree(notifier->subdevs);
> + notifier->subdevs = NULL;
> +}
> +EXPORT_SYMBOL_GPL(v4l2_async_notifier_cleanup);
> +
>  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 40b2fbfe8865..df0695b7bbcc 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 {
> @@ -388,6 +390,200 @@ 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_type = V4L2_ASYNC_MATCH_FWNODE;
> + asd->match.fwnode.fwnode =
> + fwnode_graph_get_remote_port_parent(endpoint);
> + if (!asd->match.fwnode.fwnode) {
> + 

[PATCH v2] [media] dvb-frontends/stv0910: prevent consecutive mutex_unlock()'s

2017-10-26 Thread Daniel Scheller
From: Daniel Scheller 

When calling gate_ctrl() with enable=0 if previously the mutex wasn't
locked (ie. on enable=1 failure and subdrivers not handling this properly,
or by otherwise badly behaving drivers), the i2c_lock could be unlocked
consecutively which isn't allowed. Prevent this by checking the lock
state, and actually call mutex_unlock() only when certain the lock
is actually held.

Signed-off-by: Daniel Scheller 
Tested-by: Jasmin Jessich 
Cc: Ralph Metzler 
---
Changes from v1 to v2:
 - use mutex_is_locked() instead of tracking the lock state in a separate
   variable
 - print message to KERN_DEBUG after a double unlock was prevented

 drivers/media/dvb-frontends/stv0910.c | 24 
 1 file changed, 20 insertions(+), 4 deletions(-)

diff --git a/drivers/media/dvb-frontends/stv0910.c 
b/drivers/media/dvb-frontends/stv0910.c
index 73f6df0abbfe..5d0146782488 100644
--- a/drivers/media/dvb-frontends/stv0910.c
+++ b/drivers/media/dvb-frontends/stv0910.c
@@ -1240,8 +1240,17 @@ static int gate_ctrl(struct dvb_frontend *fe, int enable)
 
if (write_reg(state, state->nr ? RSTV0910_P2_I2CRPT :
  RSTV0910_P1_I2CRPT, i2crpt) < 0) {
-   /* don't hold the I2C bus lock on failure */
-   mutex_unlock(>base->i2c_lock);
+   /*
+* don't hold the I2C bus lock on failure while preventing
+* consecutive and disallowed calls to mutex_unlock()
+*/
+   if (mutex_is_locked(>base->i2c_lock))
+   mutex_unlock(>base->i2c_lock);
+   else
+   dev_dbg(>base->i2c->dev,
+   "%s(): prevented consecutive mutex_unlock\n",
+   __func__);
+
dev_err(>base->i2c->dev,
"%s() write_reg failure (enable=%d)\n",
__func__, enable);
@@ -1250,8 +1259,15 @@ static int gate_ctrl(struct dvb_frontend *fe, int enable)
 
state->i2crpt = i2crpt;
 
-   if (!enable)
-   mutex_unlock(>base->i2c_lock);
+   if (!enable) {
+   if (mutex_is_locked(>base->i2c_lock))
+   mutex_unlock(>base->i2c_lock);
+   else
+   dev_dbg(>base->i2c->dev,
+   "%s(): prevented consecutive mutex_unlock\n",
+   __func__);
+   }
+
return 0;
 }
 
-- 
2.13.6



Re: [PATCH] media: av7110: switch to useing timer_setup()

2017-10-26 Thread kbuild test robot
Hi Dmitry,

Thank you for the patch! Yet we hit a small issue.
[auto build test ERROR on linuxtv-media/master]
[also build test ERROR on v4.14-rc6 next-20171018]
[if your patch is applied to the wrong git tree, please drop us a note to help 
improve the system]

url:
https://github.com/0day-ci/linux/commits/Dmitry-Torokhov/media-av7110-switch-to-useing-timer_setup/20171027-014646
base:   git://linuxtv.org/media_tree.git master
config: x86_64-randconfig-x001-201743 (attached as .config)
compiler: gcc-6 (Debian 6.2.0-3) 6.2.0 20160901
reproduce:
# save the attached .config to linux build tree
make ARCH=x86_64 

All error/warnings (new ones prefixed by >>):

   In file included from include/linux/list.h:8:0,
from include/linux/module.h:9,
from drivers/media//pci/ttpci/av7110_ir.c:24:
   drivers/media//pci/ttpci/av7110_ir.c: In function 'av7110_emit_keyup':
>> drivers/media//pci/ttpci/av7110_ir.c:89:39: error: 'keyup_timer' undeclared 
>> (first use in this function)
 struct infrared *ir = from_timer(ir, keyup_timer, t);
  ^
   include/linux/kernel.h:927:26: note: in definition of macro 'container_of'
 void *__mptr = (void *)(ptr); \
 ^~~
>> drivers/media//pci/ttpci/av7110_ir.c:89:24: note: in expansion of macro 
>> 'from_timer'
 struct infrared *ir = from_timer(ir, keyup_timer, t);
   ^~
   drivers/media//pci/ttpci/av7110_ir.c:89:39: note: each undeclared identifier 
is reported only once for each function it appears in
 struct infrared *ir = from_timer(ir, keyup_timer, t);
  ^
   include/linux/kernel.h:927:26: note: in definition of macro 'container_of'
 void *__mptr = (void *)(ptr); \
 ^~~
>> drivers/media//pci/ttpci/av7110_ir.c:89:24: note: in expansion of macro 
>> 'from_timer'
 struct infrared *ir = from_timer(ir, keyup_timer, t);
   ^~
   In file included from include/uapi/linux/stddef.h:1:0,
from include/linux/stddef.h:4,
from include/uapi/linux/posix_types.h:4,
from include/uapi/linux/types.h:13,
from include/linux/types.h:5,
from drivers/media//pci/ttpci/av7110_ir.c:22:
>> include/linux/kernel.h:928:51: error: 'struct infrared' has no member named 
>> 't'
 BUILD_BUG_ON_MSG(!__same_type(*(ptr), ((type *)0)->member) && \
  ^
   include/linux/compiler.h:553:19: note: in definition of macro 
'__compiletime_assert'
  bool __cond = !(condition);\
  ^
   include/linux/compiler.h:576:2: note: in expansion of macro 
'_compiletime_assert'
 _compiletime_assert(condition, msg, __compiletime_assert_, __LINE__)
 ^~~
   include/linux/build_bug.h:46:37: note: in expansion of macro 
'compiletime_assert'
#define BUILD_BUG_ON_MSG(cond, msg) compiletime_assert(!(cond), msg)
^~
   include/linux/kernel.h:928:2: note: in expansion of macro 'BUILD_BUG_ON_MSG'
 BUILD_BUG_ON_MSG(!__same_type(*(ptr), ((type *)0)->member) && \
 ^~~~
   include/linux/kernel.h:928:20: note: in expansion of macro '__same_type'
 BUILD_BUG_ON_MSG(!__same_type(*(ptr), ((type *)0)->member) && \
   ^~~
   include/linux/timer.h:183:2: note: in expansion of macro 'container_of'
 container_of(callback_timer, typeof(*var), timer_fieldname)
 ^~~~
>> drivers/media//pci/ttpci/av7110_ir.c:89:24: note: in expansion of macro 
>> 'from_timer'
 struct infrared *ir = from_timer(ir, keyup_timer, t);
   ^~
   In file included from include/linux/compiler.h:58:0,
from include/uapi/linux/stddef.h:1,
from include/linux/stddef.h:4,
from include/uapi/linux/posix_types.h:4,
from include/uapi/linux/types.h:13,
from include/linux/types.h:5,
from drivers/media//pci/ttpci/av7110_ir.c:22:
>> include/linux/compiler-gcc.h:165:2: error: 'struct infrared' has no member 
>> named 't'
 __builtin_offsetof(a, b)
 ^
   include/linux/stddef.h:16:32: note: in expansion of macro 
'__compiler_offsetof'
#define offsetof(TYPE, MEMBER) __compiler_offsetof(TYPE, MEMBER)
   ^~~
   include/linux/kernel.h:931:21: note: in expansion of macro 'offsetof'
 ((type *)(__mptr - offsetof(type, member))); })
^~~~
   include/linux/timer.h:183:2: note: in expansion of macro 'container_of'
 container_of(callback_timer, typeof(*var), timer_fieldname)
 ^~~~
>> drivers/media//pci/ttpci/av7110_ir.c:89:24: note: in expansion of 

[PATCH v3] drm: bridge: synopsys/dw-hdmi: Enable cec clock

2017-10-26 Thread Pierre-Hugues Husson
The documentation already mentions "cec" optional clock, but
currently the driver doesn't enable it.

Changes:
v3:
- Drop useless braces

v2:
- Separate ENOENT errors from others
- Propagate other errors (especially -EPROBE_DEFER)

Signed-off-by: Pierre-Hugues Husson 
---
 drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 25 +
 1 file changed, 25 insertions(+)

diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c 
b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
index bf14214fa464..d82b9747a979 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
@@ -138,6 +138,7 @@ struct dw_hdmi {
struct device *dev;
struct clk *isfr_clk;
struct clk *iahb_clk;
+   struct clk *cec_clk;
struct dw_hdmi_i2c *i2c;
 
struct hdmi_data_info hdmi_data;
@@ -2382,6 +2383,26 @@ __dw_hdmi_probe(struct platform_device *pdev,
goto err_isfr;
}
 
+   hdmi->cec_clk = devm_clk_get(hdmi->dev, "cec");
+   if (PTR_ERR(hdmi->cec_clk) == -ENOENT) {
+   hdmi->cec_clk = NULL;
+   } else if (IS_ERR(hdmi->cec_clk)) {
+   ret = PTR_ERR(hdmi->cec_clk);
+   if (ret != -EPROBE_DEFER)
+   dev_err(hdmi->dev, "Cannot get HDMI cec clock: %d\n",
+   ret);
+
+   hdmi->cec_clk = NULL;
+   goto err_iahb;
+   } else {
+   ret = clk_prepare_enable(hdmi->cec_clk);
+   if (ret) {
+   dev_err(hdmi->dev, "Cannot enable HDMI cec clock: %d\n",
+   ret);
+   goto err_iahb;
+   }
+   }
+
/* Product and revision IDs */
hdmi->version = (hdmi_readb(hdmi, HDMI_DESIGN_ID) << 8)
  | (hdmi_readb(hdmi, HDMI_REVISION_ID) << 0);
@@ -2518,6 +2539,8 @@ __dw_hdmi_probe(struct platform_device *pdev,
cec_notifier_put(hdmi->cec_notifier);
 
clk_disable_unprepare(hdmi->iahb_clk);
+   if (hdmi->cec_clk)
+   clk_disable_unprepare(hdmi->cec_clk);
 err_isfr:
clk_disable_unprepare(hdmi->isfr_clk);
 err_res:
@@ -2541,6 +2564,8 @@ static void __dw_hdmi_remove(struct dw_hdmi *hdmi)
 
clk_disable_unprepare(hdmi->iahb_clk);
clk_disable_unprepare(hdmi->isfr_clk);
+   if (hdmi->cec_clk)
+   clk_disable_unprepare(hdmi->cec_clk);
 
if (hdmi->i2c)
i2c_del_adapter(>i2c->adap);
-- 
2.14.2



camss: camera controls missing on vfe interfaces

2017-10-26 Thread Daniel Mack
Hi Todor,

When using the camss driver trough one of its /dev/videoX device nodes,
applications are currently unable to see the video controls the camera
sensor exposes.

Same goes for other ioctls such as VIDIOC_ENUM_FMT, so the only valid
resolution setting for applications to use is the one that was
previously set through the media controller layer. Applications usually
query the available formats and then pick one using the standard V4L2
APIs, and many can't easily be forced to use a specific one.

If I'm getting this right, could you explain what's the rationale here?
Is that simply a missing feature or was that approach chosen on purpose?


Thanks,
Daniel



Re: [PATCH v16 06/32] v4l: async: Use more intuitive names for internal functions

2017-10-26 Thread Niklas Söderlund
On 2017-10-26 10:53:16 +0300, Sakari Ailus wrote:
> 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 
> Reviewed-by: Sebastian Reichel 

Acked-by: Niklas Söderlund 

> ---
>  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 cde2cf2ab4b0..8b84fea50c2a 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;
>  
> @@ -187,11 +187,11 @@ int v4l2_async_notifier_register(struct v4l2_device 
> *v4l2_dev,
>   list_for_each_entry_safe(sd, tmp, _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(_lock);
>   return ret;
> @@ -255,13 +255,14 @@ int v4l2_async_register_subdev(struct v4l2_subdev *sd)
>   INIT_LIST_HEAD(>async_list);
>  
>   list_for_each_entry(notifier, _list, list) {
> - struct v4l2_async_subdev *asd = v4l2_async_belongs(notifier, 
> sd);
> + struct v4l2_async_subdev *asd = v4l2_async_find_match(notifier,
> +   sd);
>   int ret;
>  
>   if (!asd)
>   continue;
>  
> - ret = v4l2_async_test_notify(notifier, sd, asd);
> + ret = v4l2_async_match_notify(notifier, sd, asd);
>   if (ret)
>   goto err_unlock;
>  
> -- 
> 2.11.0
> 

-- 
Regards,
Niklas Söderlund


Re: [PATCH v16 05/32] v4l: async: Correctly serialise async sub-device unregistration

2017-10-26 Thread Niklas Söderlund
On 2017-10-26 10:53:15 +0300, Sakari Ailus wrote:
> The check whether an async sub-device is bound to a notifier was performed
> without list_lock held, making it possible for another process to
> unbind the async sub-device before the sub-device unregistration function
> proceeds to take the lock.
> 
> Fix this by first acquiring the lock and then proceeding with the check.
> 
> Signed-off-by: Sakari Ailus 
> Reviewed-by: Sebastian Reichel 
> Acked-by: Hans Verkuil 

Acked-by: Niklas Söderlund 

> ---
>  drivers/media/v4l2-core/v4l2-async.c | 18 +++---
>  1 file changed, 7 insertions(+), 11 deletions(-)
> 
> diff --git a/drivers/media/v4l2-core/v4l2-async.c 
> b/drivers/media/v4l2-core/v4l2-async.c
> index 4924481451ca..cde2cf2ab4b0 100644
> --- a/drivers/media/v4l2-core/v4l2-async.c
> +++ b/drivers/media/v4l2-core/v4l2-async.c
> @@ -298,20 +298,16 @@ EXPORT_SYMBOL(v4l2_async_register_subdev);
>  
>  void v4l2_async_unregister_subdev(struct v4l2_subdev *sd)
>  {
> - struct v4l2_async_notifier *notifier = sd->notifier;
> -
> - if (!sd->asd) {
> - if (!list_empty(>async_list))
> - v4l2_async_cleanup(sd);
> - return;
> - }
> -
>   mutex_lock(_lock);
>  
> - list_add(>asd->list, >waiting);
> + if (sd->asd) {
> + struct v4l2_async_notifier *notifier = sd->notifier;
>  
> - if (notifier->unbind)
> - notifier->unbind(notifier, sd, sd->asd);
> + list_add(>asd->list, >waiting);
> +
> + if (notifier->unbind)
> + notifier->unbind(notifier, sd, sd->asd);
> + }
>  
>   v4l2_async_cleanup(sd);
>  
> -- 
> 2.11.0
> 

-- 
Regards,
Niklas Söderlund


Re: [PATCH v16 04/32] v4l: async: Fix notifier complete callback error handling

2017-10-26 Thread Niklas Söderlund
Hi Sakari,

On 2017-10-26 10:53:14 +0300, Sakari Ailus wrote:
> The notifier complete callback may return an error. This error code was
> simply returned to the caller but never handled properly.
> 
> Move calling the complete callback function to the caller from
> v4l2_async_test_notify and undo the work that was done either in async
> sub-device or async notifier registration.
> 
> Reported-by: Russell King 
> Signed-off-by: Sakari Ailus 

We really should get rid of the complete handler at some point :-)

Acked-by: Niklas Söderlund 

> ---
>  drivers/media/v4l2-core/v4l2-async.c | 78 
> +++-
>  1 file changed, 60 insertions(+), 18 deletions(-)
> 
> diff --git a/drivers/media/v4l2-core/v4l2-async.c 
> b/drivers/media/v4l2-core/v4l2-async.c
> index ca281438a0ae..4924481451ca 100644
> --- a/drivers/media/v4l2-core/v4l2-async.c
> +++ b/drivers/media/v4l2-core/v4l2-async.c
> @@ -122,9 +122,6 @@ static int v4l2_async_test_notify(struct 
> v4l2_async_notifier *notifier,
>   /* Move from the global subdevice list to notifier's done */
>   list_move(>async_list, >done);
>  
> - if (list_empty(>waiting) && notifier->complete)
> - return notifier->complete(notifier);
> -
>   return 0;
>  }
>  
> @@ -136,11 +133,27 @@ static void v4l2_async_cleanup(struct v4l2_subdev *sd)
>   sd->asd = NULL;
>  }
>  
> +static void v4l2_async_notifier_unbind_all_subdevs(
> + struct v4l2_async_notifier *notifier)
> +{
> + struct v4l2_subdev *sd, *tmp;
> +
> + list_for_each_entry_safe(sd, tmp, >done, async_list) {
> + if (notifier->unbind)
> + notifier->unbind(notifier, sd, sd->asd);
> +
> + v4l2_async_cleanup(sd);
> +
> + list_move(>async_list, _list);
> + }
> +}
> +
>  int v4l2_async_notifier_register(struct v4l2_device *v4l2_dev,
>struct v4l2_async_notifier *notifier)
>  {
>   struct v4l2_subdev *sd, *tmp;
>   struct v4l2_async_subdev *asd;
> + int ret;
>   int i;
>  
>   if (!v4l2_dev || !notifier->num_subdevs ||
> @@ -185,19 +198,30 @@ int v4l2_async_notifier_register(struct v4l2_device 
> *v4l2_dev,
>   }
>   }
>  
> + if (list_empty(>waiting) && notifier->complete) {
> + ret = notifier->complete(notifier);
> + if (ret)
> + goto err_complete;
> + }
> +
>   /* Keep also completed notifiers on the list */
>   list_add(>list, _list);
>  
>   mutex_unlock(_lock);
>  
>   return 0;
> +
> +err_complete:
> + v4l2_async_notifier_unbind_all_subdevs(notifier);
> +
> + mutex_unlock(_lock);
> +
> + return ret;
>  }
>  EXPORT_SYMBOL(v4l2_async_notifier_register);
>  
>  void v4l2_async_notifier_unregister(struct v4l2_async_notifier *notifier)
>  {
> - struct v4l2_subdev *sd, *tmp;
> -
>   if (!notifier->v4l2_dev)
>   return;
>  
> @@ -205,14 +229,7 @@ void v4l2_async_notifier_unregister(struct 
> v4l2_async_notifier *notifier)
>  
>   list_del(>list);
>  
> - list_for_each_entry_safe(sd, tmp, >done, async_list) {
> - if (notifier->unbind)
> - notifier->unbind(notifier, sd, sd->asd);
> -
> - v4l2_async_cleanup(sd);
> -
> - list_move(>async_list, _list);
> - }
> + v4l2_async_notifier_unbind_all_subdevs(notifier);
>  
>   mutex_unlock(_lock);
>  
> @@ -223,6 +240,7 @@ EXPORT_SYMBOL(v4l2_async_notifier_unregister);
>  int v4l2_async_register_subdev(struct v4l2_subdev *sd)
>  {
>   struct v4l2_async_notifier *notifier;
> + int ret;
>  
>   /*
>* No reference taken. The reference is held by the device
> @@ -238,19 +256,43 @@ int v4l2_async_register_subdev(struct v4l2_subdev *sd)
>  
>   list_for_each_entry(notifier, _list, list) {
>   struct v4l2_async_subdev *asd = v4l2_async_belongs(notifier, 
> sd);
> - if (asd) {
> - int ret = v4l2_async_test_notify(notifier, sd, asd);
> - mutex_unlock(_lock);
> - return ret;
> - }
> + int ret;
> +
> + if (!asd)
> + continue;
> +
> + ret = v4l2_async_test_notify(notifier, sd, asd);
> + if (ret)
> + goto err_unlock;
> +
> + if (!list_empty(>waiting) || !notifier->complete)
> + goto out_unlock;
> +
> + ret = notifier->complete(notifier);
> + if (ret)
> + goto err_cleanup;
> +
> + goto out_unlock;
>   }
>  
>   /* None matched, wait for hot-plugging */
>   list_add(>async_list, _list);
>  
> +out_unlock:
>   mutex_unlock(_lock);
>  
>   return 0;
> +
> +err_cleanup:
> + if (notifier->unbind)
> + 

Re: [PATCH v16 02/32] v4l: async: Don't set sd->dev NULL in v4l2_async_cleanup

2017-10-26 Thread Niklas Söderlund
On 2017-10-26 10:53:12 +0300, Sakari Ailus wrote:
> v4l2_async_cleanup() is called when the async sub-device is unbound from
> the media device. As the pointer is set by the driver registering the
> async sub-device, leave the pointer as set by the driver.
> 
> Signed-off-by: Sakari Ailus 
> Reviewed-by: Sebastian Reichel 
> Acked-by: Hans Verkuil 

Acked-by: Niklas Söderlund 

> ---
>  drivers/media/v4l2-core/v4l2-async.c | 1 -
>  1 file changed, 1 deletion(-)
> 
> diff --git a/drivers/media/v4l2-core/v4l2-async.c 
> b/drivers/media/v4l2-core/v4l2-async.c
> index 60a1a50b9537..21c748bf3a7b 100644
> --- a/drivers/media/v4l2-core/v4l2-async.c
> +++ b/drivers/media/v4l2-core/v4l2-async.c
> @@ -134,7 +134,6 @@ static void v4l2_async_cleanup(struct v4l2_subdev *sd)
>   /* Subdevice driver will reprobe and put the subdev back onto the list 
> */
>   list_del_init(>async_list);
>   sd->asd = NULL;
> - sd->dev = NULL;
>  }
>  
>  int v4l2_async_notifier_register(struct v4l2_device *v4l2_dev,
> -- 
> 2.11.0
> 

-- 
Regards,
Niklas Söderlund


Re: [PATCH v16 01/32] v4l: async: Remove re-probing support

2017-10-26 Thread Niklas Söderlund
On 2017-10-26 10:53:11 +0300, Sakari Ailus wrote:
> 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
> explicitly 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.
> 
> If there is a need to support the clock provider unregister/register cycle
> while keeping the clock references in the consumers in the future, this
> should be implemented in the clock framework instead, not in V4L2.
> 
> Signed-off-by: Sakari Ailus 
> Acked-by: Hans Verkuil 
> Acked-by: Laurent Pinchart 
> Reviewed-by: Sebastian Reichel 

Acked-by: Niklas Söderlund 

> ---
>  drivers/media/v4l2-core/v4l2-async.c | 54 
> +---
>  1 file changed, 1 insertion(+), 53 deletions(-)
> 
> diff --git a/drivers/media/v4l2-core/v4l2-async.c 
> b/drivers/media/v4l2-core/v4l2-async.c
> index d741a8e0fdac..60a1a50b9537 100644
> --- a/drivers/media/v4l2-core/v4l2-async.c
> +++ b/drivers/media/v4l2-core/v4l2-async.c
> @@ -198,78 +198,26 @@ 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(_lock);
>  
>   list_del(>list);
>  
>   list_for_each_entry_safe(sd, tmp, >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);
> + list_move(>async_list, _list);
>   }
>  
>   mutex_unlock(_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
> 

-- 
Regards,
Niklas Söderlund


[PATCH v16.1 25/32] v4l: fwnode: Add convenience function for parsing common external refs

2017-10-26 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 
---
since v16:

- use const char * const *props for string arrays with property names.

 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 f8cd88f791c4..39387dc6cadd 100644
--- a/drivers/media/v4l2-core/v4l2-fwnode.c
+++ b/drivers/media/v4l2-core/v4l2-fwnode.c
@@ -865,6 +865,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 * const led_props[] = { "led" };
+   static const struct {
+   const char *name;
+   const char * const *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 17c4ac7c73e8..8d8cfc3f3100 100644
--- a/include/media/v4l2-async.h
+++ b/include/media/v4l2-async.h
@@ -156,7 +156,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 but not the notifier
  * itself. The user is responsible for calling this function to clean up the
- * notifier after calling @v4l2_async_notifier_parse_fwnode_endpoints.
+ * notifier after calling @v4l2_async_notifier_parse_fwnode_endpoints or
+ * @v4l2_fwnode_reference_parse_sensor_common.
  *
  * There is no harm from calling v4l2_async_notifier_cleanup 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 105cfeee44ef..ca50108dfd8f 100644
--- a/include/media/v4l2-fwnode.h
+++ b/include/media/v4l2-fwnode.h
@@ -319,4 +319,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 v16.1 24/32] v4l: fwnode: Add a helper function to obtain device / integer references

2017-10-26 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 
Acked-by: Hans Verkuil 
---
since v16:

- use const char * const *props for string arrays with property names.

 drivers/media/v4l2-core/v4l2-fwnode.c | 287 ++
 1 file changed, 287 insertions(+)

diff --git a/drivers/media/v4l2-core/v4l2-fwnode.c 
b/drivers/media/v4l2-core/v4l2-fwnode.c
index edd2e8d983a1..f8cd88f791c4 100644
--- a/drivers/media/v4l2-core/v4l2-fwnode.c
+++ b/drivers/media/v4l2-core/v4l2-fwnode.c
@@ -578,6 +578,293 @@ static int v4l2_fwnode_reference_parse(
return ret;
 }
 
+/*
+ * v4l2_fwnode_reference_get_int_prop - parse a reference with integer
+ * arguments
+ * @fwnode: fwnode to read @prop from
+ * @notifier: notifier for @dev
+ * @prop: the name of the property
+ * @index: the index of the reference to get
+ * @props: the array of integer property names
+ * @nprops: the number of integer property names in @nprops
+ *
+ * First find an fwnode referred to by the reference at @index in @prop.
+ *
+ * Then under that fwnode, @nprops times, for each property in @props,
+ * iteratively follow child nodes starting from fwnode such that they have the
+ * property in @props array at the index of the child node distance from the
+ * root node and the value of that property matching with the integer argument
+ * of the reference, at the same index.
+ *
+ * The child fwnode reched at the end of the iteration is then returned to the
+ * caller.
+ *
+ * The core reason for this is that you cannot refer to just any node in ACPI.
+ * So to refer to an endpoint (easy in DT) you need to refer to a device, then
+ * provide a list of (property name, property value) tuples where each tuple
+ * uniquely identifies a child node. The first tuple identifies a child 
directly
+ * underneath the device fwnode, the next tuple identifies a child node
+ * underneath the fwnode identified by the previous tuple, etc. until you
+ * reached the fwnode you need.
+ *
+ * An example with a graph, as defined in Documentation/acpi/dsd/graph.txt:
+ *
+ * Scope (\_SB.PCI0.I2C2)
+ * {
+ * Device (CAM0)
+ * {
+ * Name (_DSD, Package () {
+ * ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
+ * Package () {
+ * Package () {
+ * "compatible",
+ * Package () { "nokia,smia" }
+ * },
+ * },
+ * ToUUID("dbb8e3e6-5886-4ba6-8795-1319f52a966b"),
+ * Package () {
+ * Package () { "port0", "PRT0" },
+ * }
+ * })
+ * Name (PRT0, Package() {
+ * ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
+ * Package () {
+ * Package () { "port", 0 },
+ * },
+ * ToUUID("dbb8e3e6-5886-4ba6-8795-1319f52a966b"),
+ * Package () {
+ * Package () { "endpoint0", "EP00" },
+ * }
+ * })
+ * Name (EP00, Package() {
+ * ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
+ * Package () {
+ * Package () { "endpoint", 0 },
+ * Package () {
+ * "remote-endpoint",
+ * Package() {
+ * \_SB.PCI0.ISP, 4, 0
+ * }
+ * },
+ * }
+ * })
+ * }
+ * }
+ *
+ * Scope (\_SB.PCI0)
+ * {
+ * Device (ISP)
+ * {
+ * Name (_DSD, Package () {
+ * ToUUID("dbb8e3e6-5886-4ba6-8795-1319f52a966b"),
+ * Package () {
+ * Package () { "port4", "PRT4" },
+ * }
+ * })
+ *
+ * Name (PRT4, Package() {
+ * ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
+ * Package () {
+ * Package () { "port", 4 },
+ *   

Re: [PATCH v6 3/3] intel-ipu3: cio2: Add new MIPI-CSI2 driver

2017-10-26 Thread Sakari Ailus
Hi Yong,

Thanks for the update! A few minor comments still... please see below.

On Wed, Oct 25, 2017 at 09:24:42PM -0500, Yong Zhi wrote:
> This patch adds CIO2 CSI-2 device driver for
> Intel's IPU3 camera sub-system support.
> 
> Signed-off-by: Yong Zhi 
> Signed-off-by: Hyungwoo Yang 
> Signed-off-by: Rajmohan Mani 
> Signed-off-by: Vijaykumar Ramya 
> ---
>  drivers/media/pci/Kconfig|2 +
>  drivers/media/pci/Makefile   |3 +-
>  drivers/media/pci/intel/Makefile |5 +
>  drivers/media/pci/intel/ipu3/Kconfig |   19 +
>  drivers/media/pci/intel/ipu3/Makefile|1 +
>  drivers/media/pci/intel/ipu3/ipu3-cio2.c | 2014 
> ++
>  drivers/media/pci/intel/ipu3/ipu3-cio2.h |  449 +++
>  7 files changed, 2492 insertions(+), 1 deletion(-)
>  create mode 100644 drivers/media/pci/intel/Makefile
>  create mode 100644 drivers/media/pci/intel/ipu3/Kconfig
>  create mode 100644 drivers/media/pci/intel/ipu3/Makefile
>  create mode 100644 drivers/media/pci/intel/ipu3/ipu3-cio2.c
>  create mode 100644 drivers/media/pci/intel/ipu3/ipu3-cio2.h
> 
> diff --git a/drivers/media/pci/Kconfig b/drivers/media/pci/Kconfig
> index da28e68c87d8..5932e225f9c0 100644
> --- a/drivers/media/pci/Kconfig
> +++ b/drivers/media/pci/Kconfig
> @@ -54,5 +54,7 @@ source "drivers/media/pci/smipcie/Kconfig"
>  source "drivers/media/pci/netup_unidvb/Kconfig"
>  endif
>  
> +source "drivers/media/pci/intel/ipu3/Kconfig"
> +
>  endif #MEDIA_PCI_SUPPORT
>  endif #PCI
> diff --git a/drivers/media/pci/Makefile b/drivers/media/pci/Makefile
> index a7e8af0f64a7..d8f98434fb8c 100644
> --- a/drivers/media/pci/Makefile
> +++ b/drivers/media/pci/Makefile
> @@ -13,7 +13,8 @@ obj-y+= ttpci/  \
>   ddbridge/   \
>   saa7146/\
>   smipcie/\
> - netup_unidvb/
> + netup_unidvb/   \
> + intel/
>  
>  obj-$(CONFIG_VIDEO_IVTV) += ivtv/
>  obj-$(CONFIG_VIDEO_ZORAN) += zoran/
> diff --git a/drivers/media/pci/intel/Makefile 
> b/drivers/media/pci/intel/Makefile
> new file mode 100644
> index ..745c8b2a7819
> --- /dev/null
> +++ b/drivers/media/pci/intel/Makefile
> @@ -0,0 +1,5 @@
> +#
> +# Makefile for the IPU3 cio2 and ImGU drivers
> +#
> +
> +obj-y+= ipu3/
> diff --git a/drivers/media/pci/intel/ipu3/Kconfig 
> b/drivers/media/pci/intel/ipu3/Kconfig
> new file mode 100644
> index ..4bb8e0e97e49
> --- /dev/null
> +++ b/drivers/media/pci/intel/ipu3/Kconfig
> @@ -0,0 +1,19 @@
> +config VIDEO_IPU3_CIO2
> + tristate "Intel ipu3-cio2 driver"
> + depends on VIDEO_V4L2 && PCI
> + depends on VIDEO_V4L2_SUBDEV_API
> + depends on MEDIA_CONTROLLER
> + depends on X86 || COMPILE_TEST
> + depends on HAS_DMA
> + depends on ACPI
> + select V4L2_FWNODE
> + select VIDEOBUF2_DMA_SG
> +
> + ---help---
> + This is the Intel IPU3 CIO2 CSI-2 receiver unit, found in Intel
> + Skylake and Kaby Lake SoCs and used for capturing images and
> + video from a camera sensor.
> +
> + Say Y or M here if you have a Skylake/Kaby Lake SoC with MIPI CSI-2
> + connected camera.
> + The module will be called ipu3-cio2.
> diff --git a/drivers/media/pci/intel/ipu3/Makefile 
> b/drivers/media/pci/intel/ipu3/Makefile
> new file mode 100644
> index ..20186e3ff2ae
> --- /dev/null
> +++ b/drivers/media/pci/intel/ipu3/Makefile
> @@ -0,0 +1 @@
> +obj-$(CONFIG_VIDEO_IPU3_CIO2) += ipu3-cio2.o
> diff --git a/drivers/media/pci/intel/ipu3/ipu3-cio2.c 
> b/drivers/media/pci/intel/ipu3/ipu3-cio2.c
> new file mode 100644
> index ..8c0feda77c74
> --- /dev/null
> +++ b/drivers/media/pci/intel/ipu3/ipu3-cio2.c
> @@ -0,0 +1,2014 @@
> +/*
> + * Copyright (c) 2017 Intel Corporation.
> + *
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public License version
> + * 2 as published by the Free Software Foundation.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + *
> + * Based partially on Intel IPU4 driver written by
> + *  Sakari Ailus 
> + *  Samu Onkalo 
> + *  Jouni Högander 
> + *  Jouni Ukkonen 
> + *  Antti Laakso 
> + * et al.
> + *
> + */
> +
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +
> +#include "ipu3-cio2.h"
> +
> +struct ipu3_cio2_fmt {
> + u32 mbus_code;
> + u32 

Re: Enabling peer to peer device transactions for PCIe devices

2017-10-26 Thread Petrosyan, Ludwig


- Original Message -
> From: "David Laight" 
> To: "Petrosyan, Ludwig" , "Logan Gunthorpe" 
> 
> Cc: "Alexander Deucher" , "linux-kernel" 
> , "linux-rdma"
> , "linux-nvdimm" , 
> "Linux-media" ,
> "dri-devel" , "linux-pci" 
> , "John Bridgman"
> , "Felix Kuehling" , "Serguei 
> Sagalovitch"
> , "Paul Blinzer" , 
> "Christian Koenig" ,
> "Suravee Suthikulpanit" , "Ben Sander" 
> 
> Sent: Tuesday, 24 October, 2017 16:58:24
> Subject: RE: Enabling peer to peer device transactions for PCIe devices

> Please don't top post, write shorter lines, and add the odd blank line.
> Big blocks of text are hard to read quickly.
> 

OK this time I am very short. 
peer2peer works

Ludwig


[RFC PATCH 1/2] v4l2: add extended streaming operations

2017-10-26 Thread Hans Verkuil
From: Hans Verkuil 

For year 2038 and to simplify multiplanar formats.

Signed-off-by: Hans Verkuil 
---
 drivers/media/v4l2-core/v4l2-common.c|  72 +++
 drivers/media/v4l2-core/v4l2-dev.c   |   4 +
 drivers/media/v4l2-core/v4l2-ioctl.c | 146 +-
 drivers/media/v4l2-core/v4l2-mem2mem.c   |  97 +
 drivers/media/v4l2-core/videobuf2-v4l2.c | 332 +++
 include/media/v4l2-common.h  |   5 +
 include/media/v4l2-ioctl.h   |  17 ++
 include/media/v4l2-mem2mem.h |   8 +
 include/media/videobuf2-v4l2.h   |   9 +
 include/uapi/linux/videodev2.h   |  47 +
 10 files changed, 557 insertions(+), 180 deletions(-)

diff --git a/drivers/media/v4l2-core/v4l2-common.c 
b/drivers/media/v4l2-core/v4l2-common.c
index a5ea1f517291..9faa77566a32 100644
--- a/drivers/media/v4l2-core/v4l2-common.c
+++ b/drivers/media/v4l2-core/v4l2-common.c
@@ -405,3 +405,75 @@ void v4l2_get_timestamp(struct timeval *tv)
tv->tv_usec = ts.tv_nsec / NSEC_PER_USEC;
 }
 EXPORT_SYMBOL_GPL(v4l2_get_timestamp);
+
+void v4l2_ext_buffer_to_buffer(const struct v4l2_ext_buffer *e,
+  struct v4l2_buffer *b)
+{
+   u64 nsecs;
+
+   b->index = e->index;
+   b->type = e->type;
+   b->flags = e->flags;
+   b->field = e->field;
+   b->sequence = e->sequence;
+   b->memory = e->memory;
+   b->timestamp.tv_sec = div64_u64_rem(e->timestamp, NSEC_PER_SEC, );
+   b->timestamp.tv_usec = (u32)nsecs / NSEC_PER_USEC;
+   if (V4L2_TYPE_IS_MULTIPLANAR(b->type)) {
+   unsigned int i;
+
+   b->length = e->num_planes;
+   for (i = 0; i < e->num_planes; i++) {
+   b->m.planes[i].length = e->planes[i].length;
+   b->m.planes[i].bytesused = e->planes[i].bytesused;
+   b->m.planes[i].m.userptr = e->planes[i].m.userptr;
+   b->m.planes[i].data_offset = e->planes[i].data_offset;
+   memset(b->m.planes[i].reserved, 0,
+  sizeof(b->m.planes[i].reserved));
+   }
+   } else {
+   b->bytesused = e->planes[0].bytesused;
+   b->length = e->planes[0].length;
+   b->m.userptr = e->planes[0].m.userptr;
+   }
+   b->reserved2 = b->reserved = 0;
+   memset(>timecode, 0, sizeof(b->timecode));
+}
+EXPORT_SYMBOL_GPL(v4l2_ext_buffer_to_buffer);
+
+int v4l2_buffer_to_ext_buffer(const struct v4l2_buffer *b,
+ struct v4l2_ext_buffer *e)
+{
+   e->index = b->index;
+   e->type = b->type;
+   e->flags = b->flags;
+   e->field = b->field;
+   e->sequence = b->sequence;
+   e->memory = b->memory;
+   e->timestamp = b->timestamp.tv_sec * NSEC_PER_SEC +
+   b->timestamp.tv_usec * NSEC_PER_USEC;
+   if (V4L2_TYPE_IS_MULTIPLANAR(b->type)) {
+   unsigned int i;
+
+   if (b->m.planes == NULL)
+   return -EINVAL;
+   e->num_planes = b->length;
+   for (i = 0; i < e->num_planes; i++) {
+   e->planes[i].length = b->m.planes[i].length;
+   e->planes[i].bytesused = b->m.planes[i].bytesused;
+   e->planes[i].m.userptr = b->m.planes[i].m.userptr;
+   e->planes[i].data_offset = b->m.planes[i].data_offset;
+   memset(e->planes[i].reserved, 0,
+  sizeof(e->planes[i].reserved));
+   }
+   } else {
+   e->num_planes = 1;
+   e->planes[0].bytesused = b->bytesused;
+   e->planes[0].length = b->length;
+   e->planes[0].m.userptr = b->m.userptr;
+   e->planes[0].data_offset = 0;
+   }
+   memset(>reserved, 0, sizeof(e->reserved));
+   return 0;
+}
+EXPORT_SYMBOL_GPL(v4l2_buffer_to_ext_buffer);
diff --git a/drivers/media/v4l2-core/v4l2-dev.c 
b/drivers/media/v4l2-core/v4l2-dev.c
index c647ba648805..1ce80636453b 100644
--- a/drivers/media/v4l2-core/v4l2-dev.c
+++ b/drivers/media/v4l2-core/v4l2-dev.c
@@ -678,6 +678,10 @@ static void determine_valid_ioctls(struct video_device 
*vdev)
SET_VALID_IOCTL(ops, VIDIOC_PREPARE_BUF, vidioc_prepare_buf);
SET_VALID_IOCTL(ops, VIDIOC_STREAMON, vidioc_streamon);
SET_VALID_IOCTL(ops, VIDIOC_STREAMOFF, vidioc_streamoff);
+   SET_VALID_IOCTL(ops, VIDIOC_EXT_QUERYBUF, vidioc_ext_querybuf);
+   SET_VALID_IOCTL(ops, VIDIOC_EXT_QBUF, vidioc_ext_qbuf);
+   SET_VALID_IOCTL(ops, VIDIOC_EXT_DQBUF, vidioc_ext_dqbuf);
+   SET_VALID_IOCTL(ops, VIDIOC_EXT_PREPARE_BUF, 
vidioc_ext_prepare_buf);
}
 
if (is_vid || is_vbi || is_tch) {
diff --git a/drivers/media/v4l2-core/v4l2-ioctl.c 

[RFC PATCH 2/2] v4l2-core: make VIDIOC_DQEVENT y2038 proof.

2017-10-26 Thread Hans Verkuil
From: Hans Verkuil 

Signed-off-by: Hans Verkuil 
---
 drivers/media/v4l2-core/v4l2-compat-ioctl32.c |  4 +++-
 drivers/media/v4l2-core/v4l2-event.c  | 22 +++---
 drivers/media/v4l2-core/v4l2-ioctl.c  |  6 --
 include/uapi/linux/videodev2.h|  3 ++-
 4 files changed, 20 insertions(+), 15 deletions(-)

diff --git a/drivers/media/v4l2-core/v4l2-compat-ioctl32.c 
b/drivers/media/v4l2-core/v4l2-compat-ioctl32.c
index 821f2aa299ae..2d48b0bf45c0 100644
--- a/drivers/media/v4l2-core/v4l2-compat-ioctl32.c
+++ b/drivers/media/v4l2-core/v4l2-compat-ioctl32.c
@@ -790,7 +790,8 @@ struct v4l2_event32 {
__u32   sequence;
struct compat_timespec  timestamp;
__u32   id;
-   __u32   reserved[8];
+   __u64   timestamp64;
+   __u32   reserved[6];
 };
 
 static int put_v4l2_event32(struct v4l2_event *kp, struct v4l2_event32 __user 
*up)
@@ -803,6 +804,7 @@ static int put_v4l2_event32(struct v4l2_event *kp, struct 
v4l2_event32 __user *u
put_user(kp->timestamp.tv_sec, >timestamp.tv_sec) ||
put_user(kp->timestamp.tv_nsec, >timestamp.tv_nsec) ||
put_user(kp->id, >id) ||
+   put_user(kp->timestamp64, >timestamp64) ||
copy_to_user(up->reserved, kp->reserved, 8 * sizeof(__u32)))
return -EFAULT;
return 0;
diff --git a/drivers/media/v4l2-core/v4l2-event.c 
b/drivers/media/v4l2-core/v4l2-event.c
index 968c2eb08b5a..6fb85703fedf 100644
--- a/drivers/media/v4l2-core/v4l2-event.c
+++ b/drivers/media/v4l2-core/v4l2-event.c
@@ -36,6 +36,7 @@ static int __v4l2_event_dequeue(struct v4l2_fh *fh, struct 
v4l2_event *event)
 {
struct v4l2_kevent *kev;
unsigned long flags;
+   u64 nsecs;
 
spin_lock_irqsave(>vdev->fh_lock, flags);
 
@@ -56,6 +57,9 @@ static int __v4l2_event_dequeue(struct v4l2_fh *fh, struct 
v4l2_event *event)
kev->sev->in_use--;
 
spin_unlock_irqrestore(>vdev->fh_lock, flags);
+   event->timestamp.tv_sec = div64_u64_rem(event->timestamp64,
+   NSEC_PER_SEC, );
+   event->timestamp.tv_nsec = nsecs;
 
return 0;
 }
@@ -103,8 +107,8 @@ static struct v4l2_subscribed_event *v4l2_event_subscribed(
return NULL;
 }
 
-static void __v4l2_event_queue_fh(struct v4l2_fh *fh, const struct v4l2_event 
*ev,
-   const struct timespec *ts)
+static void __v4l2_event_queue_fh(struct v4l2_fh *fh,
+ const struct v4l2_event *ev, u64 ts)
 {
struct v4l2_subscribed_event *sev;
struct v4l2_kevent *kev;
@@ -152,7 +156,7 @@ static void __v4l2_event_queue_fh(struct v4l2_fh *fh, const 
struct v4l2_event *e
if (copy_payload)
kev->event.u = ev->u;
kev->event.id = ev->id;
-   kev->event.timestamp = *ts;
+   kev->event.timestamp64 = ts;
kev->event.sequence = fh->sequence;
sev->in_use++;
list_add_tail(>list, >available);
@@ -166,17 +170,15 @@ void v4l2_event_queue(struct video_device *vdev, const 
struct v4l2_event *ev)
 {
struct v4l2_fh *fh;
unsigned long flags;
-   struct timespec timestamp;
+   u64 timestamp = ktime_get_ns();
 
if (vdev == NULL)
return;
 
-   ktime_get_ts();
-
spin_lock_irqsave(>fh_lock, flags);
 
list_for_each_entry(fh, >fh_list, list)
-   __v4l2_event_queue_fh(fh, ev, );
+   __v4l2_event_queue_fh(fh, ev, timestamp);
 
spin_unlock_irqrestore(>fh_lock, flags);
 }
@@ -185,12 +187,10 @@ EXPORT_SYMBOL_GPL(v4l2_event_queue);
 void v4l2_event_queue_fh(struct v4l2_fh *fh, const struct v4l2_event *ev)
 {
unsigned long flags;
-   struct timespec timestamp;
-
-   ktime_get_ts();
+   u64 timestamp = ktime_get_ns();
 
spin_lock_irqsave(>vdev->fh_lock, flags);
-   __v4l2_event_queue_fh(fh, ev, );
+   __v4l2_event_queue_fh(fh, ev, timestamp);
spin_unlock_irqrestore(>vdev->fh_lock, flags);
 }
 EXPORT_SYMBOL_GPL(v4l2_event_queue_fh);
diff --git a/drivers/media/v4l2-core/v4l2-ioctl.c 
b/drivers/media/v4l2-core/v4l2-ioctl.c
index b014904ec3bc..b60b82978fad 100644
--- a/drivers/media/v4l2-core/v4l2-ioctl.c
+++ b/drivers/media/v4l2-core/v4l2-ioctl.c
@@ -805,10 +805,12 @@ static void v4l_print_event(const void *arg, bool 
write_only)
 {
const struct v4l2_event *p = arg;
const struct v4l2_event_ctrl *c;
+   u64 secs, nsecs;
 
-   pr_cont("type=0x%x, pending=%u, sequence=%u, id=%u, 
timestamp=%lu.%9.9lu\n",
+   secs = div64_u64_rem(p->timestamp64, NSEC_PER_SEC, );
+   pr_cont("type=0x%x, pending=%u, sequence=%u, id=%u, 
timestamp64=%llu.%9.9llu\n",
p->type, p->pending, 

[RFC PATCH 0/2] v4l2 core: simplify streaming ioctls, fix y2038

2017-10-26 Thread Hans Verkuil
From: Hans Verkuil 

These two patches have been sitting in my tree for some time. I'm posting these
just to get some discussion started.

The first patch adds new extended streaming ioctls that fix y2038 and that 
simplify
the single/multiplanar handling which is very hard on userspace at the moment. 
Note
that I dropped support for the timecode here as well, it's not used by any 
driver
other than the 'virtual' drivers.

The second fixes y2038 for the DQEVENT ioctl.

It's very preliminary and there is no documentation yet.

Regards,

Hans

Hans Verkuil (2):
  v4l2: add extended streaming operations
  v4l2-core: make VIDIOC_DQEVENT y2038 proof.

 drivers/media/v4l2-core/v4l2-common.c |  72 ++
 drivers/media/v4l2-core/v4l2-compat-ioctl32.c |   4 +-
 drivers/media/v4l2-core/v4l2-dev.c|   4 +
 drivers/media/v4l2-core/v4l2-event.c  |  22 +-
 drivers/media/v4l2-core/v4l2-ioctl.c  | 152 +++-
 drivers/media/v4l2-core/v4l2-mem2mem.c|  97 
 drivers/media/v4l2-core/videobuf2-v4l2.c  | 332 --
 include/media/v4l2-common.h   |   5 +
 include/media/v4l2-ioctl.h|  17 ++
 include/media/v4l2-mem2mem.h  |   8 +
 include/media/videobuf2-v4l2.h|   9 +
 include/uapi/linux/videodev2.h|  50 +++-
 12 files changed, 577 insertions(+), 195 deletions(-)

-- 
2.14.2



[GIT PULL for 4.15] Yet more sensor driver patches

2017-10-26 Thread Sakari Ailus
Hi Mauro,

Here's the final set of sensor driver patches for 4.15.

Please pull.


The following changes since commit 61065fc3e32002ba48aa6bc3816c1f6f9f8daf55:

  Merge commit '3728e6a255b5' into patchwork (2017-10-17 17:22:20 -0700)

are available in the git repository at:

  ssh://linuxtv.org/git/sailus/media_tree.git for-4.15-4

for you to fetch changes up to fc8d24b85bc230afe66e9aece38350384c9b65f8:

  media: ov9650: remove unnecessary terminated entry in menu items array 
(2017-10-25 19:08:43 +0300)


Akinobu Mita (5):
  media: adv7180: don't clear V4L2_SUBDEV_FL_IS_I2C
  media: max2175: don't clear V4L2_SUBDEV_FL_IS_I2C
  media: ov2640: don't clear V4L2_SUBDEV_FL_IS_I2C
  media: ov5640: don't clear V4L2_SUBDEV_FL_IS_I2C
  media: ov9650: remove unnecessary terminated entry in menu items array

Jacob Chen (2):
  media: i2c: OV5647: ensure clock lane in LP-11 state before streaming on
  media: i2c: OV5647: change to use macro for the registers

Philipp Zabel (1):
  tc358743: validate lane count

Wenyou Yang (3):
  media: ov7670: Add entity pads initialization
  media: ov7670: Add the get_fmt callback
  media: ov7670: Add the ov7670_s_power function

 drivers/media/i2c/adv7180.c  |   2 +-
 drivers/media/i2c/max2175.c  |   2 +-
 drivers/media/i2c/ov2640.c   |   2 +-
 drivers/media/i2c/ov5640.c   |   2 +-
 drivers/media/i2c/ov5647.c   |  51 -
 drivers/media/i2c/ov7670.c   | 129 ---
 drivers/media/i2c/ov9650.c   |   1 -
 drivers/media/i2c/tc358743.c |   5 ++
 8 files changed, 167 insertions(+), 27 deletions(-)

-- 
Kind regards,

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


[GIT PULL v2 for 4.15] Imx274 driver

2017-10-26 Thread Sakari Ailus
Hi Mauro,

Here's the imx274 driver, this time with the MAINTAINERS entry. A few minor
fixes have been done as well in error handling.

Please pull.


The following changes since commit 61065fc3e32002ba48aa6bc3816c1f6f9f8daf55:

  Merge commit '3728e6a255b5' into patchwork (2017-10-17 17:22:20 -0700)

are available in the git repository at:

  ssh://linuxtv.org/git/sailus/media_tree.git for-4.15-2

for you to fetch changes up to 9bcabda990b45147819a1fe38e8e6181a0f474c3:

  imx274: Add MAINTAINERS entry (2017-10-26 11:37:22 +0300)


Leon Luo (2):
  imx274: device tree binding file
  imx274: V4l2 driver for Sony imx274 CMOS sensor

Sakari Ailus (1):
  imx274: Add MAINTAINERS entry

 .../devicetree/bindings/media/i2c/imx274.txt   |   33 +
 MAINTAINERS|8 +
 drivers/media/i2c/Kconfig  |7 +
 drivers/media/i2c/Makefile |1 +
 drivers/media/i2c/imx274.c | 1810 
 5 files changed, 1859 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/media/i2c/imx274.txt
 create mode 100644 drivers/media/i2c/imx274.c


-- 
Kind regards,

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


[PATCH 1/1] imx274: Add MAINTAINERS entry

2017-10-26 Thread Sakari Ailus
Add MAINTAINERS entry for imx274 driver and DT bindings.

Signed-off-by: Leon Luo 
Signed-off-by: Sakari Ailus 
---
Hi Leon,

I moved the maintainers entry to a separate patch. It's better this way.

 MAINTAINERS | 8 
 1 file changed, 8 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 90230fe020f3..b5927bd4fe1e 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -12486,6 +12486,14 @@ S: Maintained
 F: drivers/ssb/
 F: include/linux/ssb/
 
+SONY IMX274 SENSOR DRIVER
+M: Leon Luo 
+L: linux-media@vger.kernel.org
+T: git git://linuxtv.org/media_tree.git
+S: Maintained
+F: drivers/media/i2c/imx274.c
+F: Documentation/devicetree/bindings/media/i2c/imx274.txt
+
 SONY MEMORYSTICK CARD SUPPORT
 M: Alex Dubov 
 W: http://tifmxx.berlios.de/
-- 
2.11.0



[PATCH v16 01/32] v4l: async: Remove re-probing support

2017-10-26 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
explicitly 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.

If there is a need to support the clock provider unregister/register cycle
while keeping the clock references in the consumers in the future, this
should be implemented in the clock framework instead, not in V4L2.

Signed-off-by: Sakari Ailus 
Acked-by: Hans Verkuil 
Acked-by: Laurent Pinchart 
Reviewed-by: Sebastian Reichel 
---
 drivers/media/v4l2-core/v4l2-async.c | 54 +---
 1 file changed, 1 insertion(+), 53 deletions(-)

diff --git a/drivers/media/v4l2-core/v4l2-async.c 
b/drivers/media/v4l2-core/v4l2-async.c
index d741a8e0fdac..60a1a50b9537 100644
--- a/drivers/media/v4l2-core/v4l2-async.c
+++ b/drivers/media/v4l2-core/v4l2-async.c
@@ -198,78 +198,26 @@ 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(_lock);
 
list_del(>list);
 
list_for_each_entry_safe(sd, tmp, >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);
+   list_move(>async_list, _list);
}
 
mutex_unlock(_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 v16 00/32] Unified fwnode endpoint parser, async sub-device notifier support, N9 flash DTS

2017-10-26 Thread Sakari Ailus
Hi folks,

I've dropped the full set from devicetree and linux-acpi lists;
let me know if you want it back. The entire set is posted to
linux-media list.

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:



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.

The patches have a dependency to the as3645a driver fixes:



since v15:

- Remove complete callback support from sub-device notifiers. There's no
  need for these now and likely we wish to get rid of the complete
  callback in the long run.

- Document fwnode argument and add examples and improved description
  v4l2_fwnode_reference_get_int_prop.

- Fix over 80 characters per line issue for
  v4l2_fwnode_reference_parse_int_props, as well as constify string
  arrays.

- Fix vep argument documentation for v4l2_fwnode_endpoint_free.

since v14:

- Patch "v4l: fwnode: Support generic parsing of graph endpoints in a
  device" depends on another patch "device property: preserve usecount for
  node passed to of_fwnode_graph_get_port_parent()". Add Depends-on tag.

- Add patch "v4l: async: fix unbind error in
  v4l2_async_notifier_unregister()" by Niklas. Effectively the notifier's
  unbind callback is called before v4l2_async_cleanup(), not after it.

- Fix complete callback error handling (patch "v4l: async: Fix notifier
  complete callback error handling").

- Rework error handling in in v4l2_async_match_notify() and add comments.
  No functional changes there.

- Don't assign sd->dev to NULL in v4l2_async_cleanup() (patch "v4l: async:
  Don't set sd->dev NULL in v4l2_async_cleanup").

- Introduce a function to unbind sub-devices from a notifier. This is a
  common operation so a common implementation is beneficial.

- Assign notifier's v4l2_dev (or sd for sub-device notifiers) NULL on
  failure.

- Make v4l2_async_notifier_unregister() safe to call with a NULL argument.

- Set the implicitly allocated sub-device notifier NULL on async
  sub-device unregistration (used to be a dangling pointer).

- Clean up async sub-device unregistration.

- Fix v4l2_fwnode_endpoint_free() comment to match KernelDoc style, i.e.
  make the function visible in documentation.

- Don't add a random newline near the end of v4l2_async.h.

- Move patch "v4l: fwnode: Move KernelDoc documentation to the header"
  later in the set. The five first patches should now address bugs in the
  V4L2 async framework, causing an oops on complete callback failure.

since v13:

- Add patch "v4l: fwnode: Add a convenience function for registering sensors"
  and make the sensor driver changes a lot smaller.

- Fix v4l2_async_notifier_parse_fwnode_endpoints() error handling for
  omap3isp.

- Return -ENODEV in rcar-vin if no async sub-device is available. I.e. fix
  a bug in previous versions of "rcar-vin: Use generic parser for parsing
  fwnode endpoints".

- Rework notifier completion in patch "v4l: async: Allow binding notifiers to
  sub-devices". This fixes calling complete notifiers more than once; they
  are now all called once when all async sub-devices in all related
  notifiers have been bound.

- Split the same patch ("v4l: async: Allow binding notifiers to
  sub-devices") into two, first one that prepares for async sub-devices
  and another that implements the bulk of support for sub-device notifiers.

- Postpone sub-device bound callback until v4l2_device is available in all
  cases. This also applies to the media device. The notifier's bound
  callback was in some cases called before having v4l2_device in v13.

- Prevent registering fwnodes as async sub-devices more 

[PATCH v16 13/32] v4l: async: Move async subdev notifier operations to a separate structure

2017-10-26 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   | 30 --
 drivers/staging/media/imx/imx-media-dev.c  |  8 +--
 include/media/v4l2-async.h | 29 -
 18 files changed, 135 insertions(+), 66 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 = _async_ops;
ret = v4l2_async_notifier_register(>v4l2_dev,
>notifier);
if (ret) {
diff --git a/drivers/media/platform/atmel/atmel-isc.c 
b/drivers/media/platform/atmel/atmel-isc.c
index 2f8e345d297e..382fe355e616 100644
--- a/drivers/media/platform/atmel/atmel-isc.c
+++ b/drivers/media/platform/atmel/atmel-isc.c
@@ -1637,6 +1637,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;
@@ -1849,9 +1855,7 @@ static int atmel_isc_probe(struct platform_device *pdev)
list_for_each_entry(subdev_entity, >subdev_entities, list) {
subdev_entity->notifier.subdevs = _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 = _async_ops;
 
ret = v4l2_async_notifier_register(>v4l2_dev,
   _entity->notifier);
diff --git a/drivers/media/platform/atmel/atmel-isi.c 
b/drivers/media/platform/atmel/atmel-isi.c
index 463c0146915e..e900995143a3 100644
--- a/drivers/media/platform/atmel/atmel-isi.c
+++ b/drivers/media/platform/atmel/atmel-isi.c
@@ -1103,6 +1103,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;
@@ -1150,9 +1156,7 @@ static int isi_graph_init(struct atmel_isi *isi)
 
isi->notifier.subdevs = subdevs;
isi->notifier.num_subdevs = 1;
- 

[PATCH v16 04/32] v4l: async: Fix notifier complete callback error handling

2017-10-26 Thread Sakari Ailus
The notifier complete callback may return an error. This error code was
simply returned to the caller but never handled properly.

Move calling the complete callback function to the caller from
v4l2_async_test_notify and undo the work that was done either in async
sub-device or async notifier registration.

Reported-by: Russell King 
Signed-off-by: Sakari Ailus 
---
 drivers/media/v4l2-core/v4l2-async.c | 78 +++-
 1 file changed, 60 insertions(+), 18 deletions(-)

diff --git a/drivers/media/v4l2-core/v4l2-async.c 
b/drivers/media/v4l2-core/v4l2-async.c
index ca281438a0ae..4924481451ca 100644
--- a/drivers/media/v4l2-core/v4l2-async.c
+++ b/drivers/media/v4l2-core/v4l2-async.c
@@ -122,9 +122,6 @@ static int v4l2_async_test_notify(struct 
v4l2_async_notifier *notifier,
/* Move from the global subdevice list to notifier's done */
list_move(>async_list, >done);
 
-   if (list_empty(>waiting) && notifier->complete)
-   return notifier->complete(notifier);
-
return 0;
 }
 
@@ -136,11 +133,27 @@ static void v4l2_async_cleanup(struct v4l2_subdev *sd)
sd->asd = NULL;
 }
 
+static void v4l2_async_notifier_unbind_all_subdevs(
+   struct v4l2_async_notifier *notifier)
+{
+   struct v4l2_subdev *sd, *tmp;
+
+   list_for_each_entry_safe(sd, tmp, >done, async_list) {
+   if (notifier->unbind)
+   notifier->unbind(notifier, sd, sd->asd);
+
+   v4l2_async_cleanup(sd);
+
+   list_move(>async_list, _list);
+   }
+}
+
 int v4l2_async_notifier_register(struct v4l2_device *v4l2_dev,
 struct v4l2_async_notifier *notifier)
 {
struct v4l2_subdev *sd, *tmp;
struct v4l2_async_subdev *asd;
+   int ret;
int i;
 
if (!v4l2_dev || !notifier->num_subdevs ||
@@ -185,19 +198,30 @@ int v4l2_async_notifier_register(struct v4l2_device 
*v4l2_dev,
}
}
 
+   if (list_empty(>waiting) && notifier->complete) {
+   ret = notifier->complete(notifier);
+   if (ret)
+   goto err_complete;
+   }
+
/* Keep also completed notifiers on the list */
list_add(>list, _list);
 
mutex_unlock(_lock);
 
return 0;
+
+err_complete:
+   v4l2_async_notifier_unbind_all_subdevs(notifier);
+
+   mutex_unlock(_lock);
+
+   return ret;
 }
 EXPORT_SYMBOL(v4l2_async_notifier_register);
 
 void v4l2_async_notifier_unregister(struct v4l2_async_notifier *notifier)
 {
-   struct v4l2_subdev *sd, *tmp;
-
if (!notifier->v4l2_dev)
return;
 
@@ -205,14 +229,7 @@ void v4l2_async_notifier_unregister(struct 
v4l2_async_notifier *notifier)
 
list_del(>list);
 
-   list_for_each_entry_safe(sd, tmp, >done, async_list) {
-   if (notifier->unbind)
-   notifier->unbind(notifier, sd, sd->asd);
-
-   v4l2_async_cleanup(sd);
-
-   list_move(>async_list, _list);
-   }
+   v4l2_async_notifier_unbind_all_subdevs(notifier);
 
mutex_unlock(_lock);
 
@@ -223,6 +240,7 @@ EXPORT_SYMBOL(v4l2_async_notifier_unregister);
 int v4l2_async_register_subdev(struct v4l2_subdev *sd)
 {
struct v4l2_async_notifier *notifier;
+   int ret;
 
/*
 * No reference taken. The reference is held by the device
@@ -238,19 +256,43 @@ int v4l2_async_register_subdev(struct v4l2_subdev *sd)
 
list_for_each_entry(notifier, _list, list) {
struct v4l2_async_subdev *asd = v4l2_async_belongs(notifier, 
sd);
-   if (asd) {
-   int ret = v4l2_async_test_notify(notifier, sd, asd);
-   mutex_unlock(_lock);
-   return ret;
-   }
+   int ret;
+
+   if (!asd)
+   continue;
+
+   ret = v4l2_async_test_notify(notifier, sd, asd);
+   if (ret)
+   goto err_unlock;
+
+   if (!list_empty(>waiting) || !notifier->complete)
+   goto out_unlock;
+
+   ret = notifier->complete(notifier);
+   if (ret)
+   goto err_cleanup;
+
+   goto out_unlock;
}
 
/* None matched, wait for hot-plugging */
list_add(>async_list, _list);
 
+out_unlock:
mutex_unlock(_lock);
 
return 0;
+
+err_cleanup:
+   if (notifier->unbind)
+   notifier->unbind(notifier, sd, sd->asd);
+
+   v4l2_async_cleanup(sd);
+
+err_unlock:
+   mutex_unlock(_lock);
+
+   return ret;
 }
 EXPORT_SYMBOL(v4l2_async_register_subdev);
 
-- 
2.11.0



[PATCH v16 15/32] v4l: async: Register sub-devices before calling bound callback

2017-10-26 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 
Acked-by: Pavel Machek 
---
 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 e170682dae78..46db85685894 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 v16 20/32] dt: bindings: Add a binding for flash LED devices associated to a sensor

2017-10-26 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 
Cc: Rob Herring 
Cc: devicet...@vger.kernel.org
Acked-by: Hans Verkuil 
Acked-by: Pavel Machek 
Acked-by: Rob Herring 
---
 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 bd6474920510..dc66e3224692 100644
--- a/Documentation/devicetree/bindings/media/video-interfaces.txt
+++ b/Documentation/devicetree/bindings/media/video-interfaces.txt
@@ -76,6 +76,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 v16 26/32] v4l: fwnode: Add a convenience function for registering sensors

2017-10-26 Thread Sakari Ailus
Add a convenience function for parsing firmware for information on related
devices using v4l2_async_notifier_parse_fwnode_sensor_common() registering
the notifier and finally the async sub-device itself.

This should be useful for sensor drivers that do not have device specific
requirements related to firmware information parsing or the async
framework.

Signed-off-by: Sakari Ailus 
Acked-by: Hans Verkuil 
---
 drivers/media/v4l2-core/v4l2-async.c  | 19 
 drivers/media/v4l2-core/v4l2-fwnode.c | 41 +++
 include/media/v4l2-async.h| 22 +++
 include/media/v4l2-subdev.h   |  3 +++
 4 files changed, 81 insertions(+), 4 deletions(-)

diff --git a/drivers/media/v4l2-core/v4l2-async.c 
b/drivers/media/v4l2-core/v4l2-async.c
index b4e88eef195f..e81a72b8d46e 100644
--- a/drivers/media/v4l2-core/v4l2-async.c
+++ b/drivers/media/v4l2-core/v4l2-async.c
@@ -474,19 +474,25 @@ int v4l2_async_subdev_notifier_register(struct 
v4l2_subdev *sd,
 }
 EXPORT_SYMBOL(v4l2_async_subdev_notifier_register);
 
-void v4l2_async_notifier_unregister(struct v4l2_async_notifier *notifier)
+static void __v4l2_async_notifier_unregister(
+   struct v4l2_async_notifier *notifier)
 {
-   if (!notifier->v4l2_dev && !notifier->sd)
+   if (!notifier || (!notifier->v4l2_dev && !notifier->sd))
return;
 
-   mutex_lock(_lock);
-
v4l2_async_notifier_unbind_all_subdevs(notifier);
 
notifier->sd = NULL;
notifier->v4l2_dev = NULL;
 
list_del(>list);
+}
+
+void v4l2_async_notifier_unregister(struct v4l2_async_notifier *notifier)
+{
+   mutex_lock(_lock);
+
+   __v4l2_async_notifier_unregister(notifier);
 
mutex_unlock(_lock);
 }
@@ -596,6 +602,11 @@ void v4l2_async_unregister_subdev(struct v4l2_subdev *sd)
 {
mutex_lock(_lock);
 
+   __v4l2_async_notifier_unregister(sd->subdev_notifier);
+   v4l2_async_notifier_cleanup(sd->subdev_notifier);
+   kfree(sd->subdev_notifier);
+   sd->subdev_notifier = NULL;
+
if (sd->asd) {
struct v4l2_async_notifier *notifier = sd->notifier;
 
diff --git a/drivers/media/v4l2-core/v4l2-fwnode.c 
b/drivers/media/v4l2-core/v4l2-fwnode.c
index 1234bd1a2f49..82af608fd626 100644
--- a/drivers/media/v4l2-core/v4l2-fwnode.c
+++ b/drivers/media/v4l2-core/v4l2-fwnode.c
@@ -29,6 +29,7 @@
 
 #include 
 #include 
+#include 
 
 enum v4l2_fwnode_bus_type {
V4L2_FWNODE_BUS_TYPE_GUESS = 0,
@@ -900,6 +901,46 @@ int v4l2_async_notifier_parse_fwnode_sensor_common(
 }
 EXPORT_SYMBOL_GPL(v4l2_async_notifier_parse_fwnode_sensor_common);
 
+int v4l2_async_register_subdev_sensor_common(struct v4l2_subdev *sd)
+{
+   struct v4l2_async_notifier *notifier;
+   int ret;
+
+   if (WARN_ON(!sd->dev))
+   return -ENODEV;
+
+   notifier = kzalloc(sizeof(*notifier), GFP_KERNEL);
+   if (!notifier)
+   return -ENOMEM;
+
+   ret = v4l2_async_notifier_parse_fwnode_sensor_common(sd->dev,
+notifier);
+   if (ret < 0)
+   goto out_cleanup;
+
+   ret = v4l2_async_subdev_notifier_register(sd, notifier);
+   if (ret < 0)
+   goto out_cleanup;
+
+   ret = v4l2_async_register_subdev(sd);
+   if (ret < 0)
+   goto out_unregister;
+
+   sd->subdev_notifier = notifier;
+
+   return 0;
+
+out_unregister:
+   v4l2_async_notifier_unregister(notifier);
+
+out_cleanup:
+   v4l2_async_notifier_cleanup(notifier);
+   kfree(notifier);
+
+   return ret;
+}
+EXPORT_SYMBOL_GPL(v4l2_async_register_subdev_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 8d8cfc3f3100..6152434cbe82 100644
--- a/include/media/v4l2-async.h
+++ b/include/media/v4l2-async.h
@@ -174,6 +174,28 @@ void v4l2_async_notifier_cleanup(struct 
v4l2_async_notifier *notifier);
 int v4l2_async_register_subdev(struct v4l2_subdev *sd);
 
 /**
+ * v4l2_async_register_subdev_sensor_common - registers a sensor sub-device to
+ *   the asynchronous sub-device
+ *   framework and parse set up common
+ *   sensor related devices
+ *
+ * @sd: pointer to struct _subdev
+ *
+ * This function is just like v4l2_async_register_subdev() with the exception
+ * that calling it will also parse firmware interfaces for remote references
+ * using v4l2_async_notifier_parse_fwnode_sensor_common() and registers the
+ * async sub-devices. The sub-device is similarly unregistered by calling
+ * v4l2_async_unregister_subdev().
+ *
+ * While registered, the subdev module is marked as 

[PATCH v16 22/32] v4l: fwnode: Move KernelDoc documentation to the header

2017-10-26 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 and add an asterisk to v4l2_fwnode_endpoint_free()
documentation to make it proper KernelDoc 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 df0695b7bbcc..65bdcd59744a 100644
--- a/drivers/media/v4l2-core/v4l2-fwnode.c
+++ b/drivers/media/v4l2-core/v4l2-fwnode.c
@@ -183,25 +183,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)
 {
@@ -241,14 +222,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))
@@ -259,29 +232,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)
 {
@@ -324,24 +274,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 

[PATCH v16 24/32] v4l: fwnode: Add a helper function to obtain device / integer references

2017-10-26 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 
Acked-by: Hans Verkuil 
---
 drivers/media/v4l2-core/v4l2-fwnode.c | 287 ++
 1 file changed, 287 insertions(+)

diff --git a/drivers/media/v4l2-core/v4l2-fwnode.c 
b/drivers/media/v4l2-core/v4l2-fwnode.c
index edd2e8d983a1..845ef8da9002 100644
--- a/drivers/media/v4l2-core/v4l2-fwnode.c
+++ b/drivers/media/v4l2-core/v4l2-fwnode.c
@@ -578,6 +578,293 @@ static int v4l2_fwnode_reference_parse(
return ret;
 }
 
+/*
+ * v4l2_fwnode_reference_get_int_prop - parse a reference with integer
+ * arguments
+ * @fwnode: fwnode to read @prop from
+ * @notifier: notifier for @dev
+ * @prop: the name of the property
+ * @index: the index of the reference to get
+ * @props: the array of integer property names
+ * @nprops: the number of integer property names in @nprops
+ *
+ * First find an fwnode referred to by the reference at @index in @prop.
+ *
+ * Then under that fwnode, @nprops times, for each property in @props,
+ * iteratively follow child nodes starting from fwnode such that they have the
+ * property in @props array at the index of the child node distance from the
+ * root node and the value of that property matching with the integer argument
+ * of the reference, at the same index.
+ *
+ * The child fwnode reched at the end of the iteration is then returned to the
+ * caller.
+ *
+ * The core reason for this is that you cannot refer to just any node in ACPI.
+ * So to refer to an endpoint (easy in DT) you need to refer to a device, then
+ * provide a list of (property name, property value) tuples where each tuple
+ * uniquely identifies a child node. The first tuple identifies a child 
directly
+ * underneath the device fwnode, the next tuple identifies a child node
+ * underneath the fwnode identified by the previous tuple, etc. until you
+ * reached the fwnode you need.
+ *
+ * An example with a graph, as defined in Documentation/acpi/dsd/graph.txt:
+ *
+ * Scope (\_SB.PCI0.I2C2)
+ * {
+ * Device (CAM0)
+ * {
+ * Name (_DSD, Package () {
+ * ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
+ * Package () {
+ * Package () {
+ * "compatible",
+ * Package () { "nokia,smia" }
+ * },
+ * },
+ * ToUUID("dbb8e3e6-5886-4ba6-8795-1319f52a966b"),
+ * Package () {
+ * Package () { "port0", "PRT0" },
+ * }
+ * })
+ * Name (PRT0, Package() {
+ * ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
+ * Package () {
+ * Package () { "port", 0 },
+ * },
+ * ToUUID("dbb8e3e6-5886-4ba6-8795-1319f52a966b"),
+ * Package () {
+ * Package () { "endpoint0", "EP00" },
+ * }
+ * })
+ * Name (EP00, Package() {
+ * ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
+ * Package () {
+ * Package () { "endpoint", 0 },
+ * Package () {
+ * "remote-endpoint",
+ * Package() {
+ * \_SB.PCI0.ISP, 4, 0
+ * }
+ * },
+ * }
+ * })
+ * }
+ * }
+ *
+ * Scope (\_SB.PCI0)
+ * {
+ * Device (ISP)
+ * {
+ * Name (_DSD, Package () {
+ * ToUUID("dbb8e3e6-5886-4ba6-8795-1319f52a966b"),
+ * Package () {
+ * Package () { "port4", "PRT4" },
+ * }
+ * })
+ *
+ * Name (PRT4, Package() {
+ * ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
+ * Package () {
+ * Package () { "port", 4 },
+ * },
+ * 

[PATCH v16 21/32] dt: bindings: Add lens-focus binding for image sensors

2017-10-26 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 
Cc: Rob Herring 
Cc: devicet...@vger.kernel.org
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 dc66e3224692..3994b0143dd1 100644
--- a/Documentation/devicetree/bindings/media/video-interfaces.txt
+++ b/Documentation/devicetree/bindings/media/video-interfaces.txt
@@ -83,6 +83,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 v16 30/32] ov5670: Add support for flash and lens devices

2017-10-26 Thread Sakari Ailus
Parse async sub-devices related to the sensor by switching the async
sub-device registration function.

Signed-off-by: Sakari Ailus 
Acked-by: Hans Verkuil 
---
 drivers/media/i2c/ov5670.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/media/i2c/ov5670.c b/drivers/media/i2c/ov5670.c
index a65469f88e36..9f9196568eb8 100644
--- a/drivers/media/i2c/ov5670.c
+++ b/drivers/media/i2c/ov5670.c
@@ -2529,7 +2529,7 @@ static int ov5670_probe(struct i2c_client *client)
}
 
/* Async register for subdev */
-   ret = v4l2_async_register_subdev(>sd);
+   ret = v4l2_async_register_subdev_sensor_common(>sd);
if (ret < 0) {
err_msg = "v4l2_async_register_subdev() error";
goto error_entity_cleanup;
-- 
2.11.0



[PATCH v16 29/32] et8ek8: Add support for flash and lens devices

2017-10-26 Thread Sakari Ailus
Parse async sub-devices related to the sensor by switching the async
sub-device registration function.

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

diff --git a/drivers/media/i2c/et8ek8/et8ek8_driver.c 
b/drivers/media/i2c/et8ek8/et8ek8_driver.c
index c14f0fd6ded3..e9eff9039ef5 100644
--- a/drivers/media/i2c/et8ek8/et8ek8_driver.c
+++ b/drivers/media/i2c/et8ek8/et8ek8_driver.c
@@ -1453,7 +1453,7 @@ static int et8ek8_probe(struct i2c_client *client,
goto err_mutex;
}
 
-   ret = v4l2_async_register_subdev(>subdev);
+   ret = v4l2_async_register_subdev_sensor_common(>subdev);
if (ret < 0)
goto err_entity;
 
-- 
2.11.0



[PATCH v16 23/32] v4l: fwnode: Add a helper function for parsing generic references

2017-10-26 Thread Sakari Ailus
Add function 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.

Signed-off-by: Sakari Ailus 
Acked-by: Hans Verkuil 
---
 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 65bdcd59744a..edd2e8d983a1 100644
--- a/drivers/media/v4l2-core/v4l2-fwnode.c
+++ b/drivers/media/v4l2-core/v4l2-fwnode.c
@@ -509,6 +509,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, ));
+index++)
+   fwnode_handle_put(args.fwnode);
+
+   if (!index)
+   return -ENOENT;
+
+   /*
+* Note that right now both -ENODATA and -ENOENT may signal
+* out-of-bounds access. Return the error in cases other than that.
+*/
+   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, );
+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 v16 27/32] dt: bindings: smiapp: Document lens-focus and flash-leds properties

2017-10-26 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 v16 31/32] ov13858: Add support for flash and lens devices

2017-10-26 Thread Sakari Ailus
Parse async sub-devices related to the sensor by switching the async
sub-device registration function.

Signed-off-by: Sakari Ailus 
Acked-by: Hans Verkuil 
---
 drivers/media/i2c/ov13858.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/media/i2c/ov13858.c b/drivers/media/i2c/ov13858.c
index fdce2befed02..bf7d06f3f21a 100644
--- a/drivers/media/i2c/ov13858.c
+++ b/drivers/media/i2c/ov13858.c
@@ -1761,7 +1761,7 @@ static int ov13858_probe(struct i2c_client *client,
goto error_handler_free;
}
 
-   ret = v4l2_async_register_subdev(>sd);
+   ret = v4l2_async_register_subdev_sensor_common(>sd);
if (ret < 0)
goto error_media_entity;
 
-- 
2.11.0



[PATCH v16 25/32] v4l: fwnode: Add convenience function for parsing common external refs

2017-10-26 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 845ef8da9002..1234bd1a2f49 100644
--- a/drivers/media/v4l2-core/v4l2-fwnode.c
+++ b/drivers/media/v4l2-core/v4l2-fwnode.c
@@ -865,6 +865,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 * const led_props[] = { "led" };
+   static const struct {
+   const char * const 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 17c4ac7c73e8..8d8cfc3f3100 100644
--- a/include/media/v4l2-async.h
+++ b/include/media/v4l2-async.h
@@ -156,7 +156,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 but not the notifier
  * itself. The user is responsible for calling this function to clean up the
- * notifier after calling @v4l2_async_notifier_parse_fwnode_endpoints.
+ * notifier after calling @v4l2_async_notifier_parse_fwnode_endpoints or
+ * @v4l2_fwnode_reference_parse_sensor_common.
  *
  * There is no harm from calling v4l2_async_notifier_cleanup 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 105cfeee44ef..ca50108dfd8f 100644
--- a/include/media/v4l2-fwnode.h
+++ b/include/media/v4l2-fwnode.h
@@ -319,4 +319,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 v16 28/32] smiapp: Add support for flash and lens devices

2017-10-26 Thread Sakari Ailus
Parse async sub-devices related to the sensor by switching the async
sub-device registration function.

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 | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/media/i2c/smiapp/smiapp-core.c 
b/drivers/media/i2c/smiapp/smiapp-core.c
index fbd851be51d2..a87c50373813 100644
--- a/drivers/media/i2c/smiapp/smiapp-core.c
+++ b/drivers/media/i2c/smiapp/smiapp-core.c
@@ -3118,7 +3118,7 @@ static int smiapp_probe(struct i2c_client *client,
if (rval < 0)
goto out_media_entity_cleanup;
 
-   rval = v4l2_async_register_subdev(>src->sd);
+   rval = v4l2_async_register_subdev_sensor_common(>src->sd);
if (rval < 0)
goto out_media_entity_cleanup;
 
-- 
2.11.0



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

2017-10-26 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 = < 0>;
clock-frequency = <960>;
nokia,nvm-size = <(16 * 64)>;
+   flash-leds = <_flash _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 = < 0>;
clock-frequency = <960>;
nokia,nvm-size = <(16 * 64)>;
+   flash-leds = <_flash _indicator>;
port {
smia_1_1: endpoint {
link-frequencies = /bits/ 64 <21000 
33360 39840>;
-- 
2.11.0



[PATCH v16 19/32] v4l: async: Ensure only unique fwnodes are registered to notifiers

2017-10-26 Thread Sakari Ailus
While registering a notifier, check that each newly added fwnode is
unique, and return an error if it is not. Also check that a newly added
notifier does not have the same fwnodes twice.

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

diff --git a/drivers/media/v4l2-core/v4l2-async.c 
b/drivers/media/v4l2-core/v4l2-async.c
index ed539c4fd5dc..b4e88eef195f 100644
--- a/drivers/media/v4l2-core/v4l2-async.c
+++ b/drivers/media/v4l2-core/v4l2-async.c
@@ -308,8 +308,71 @@ static void v4l2_async_notifier_unbind_all_subdevs(
notifier->parent = NULL;
 }
 
+/* See if an fwnode can be found in a notifier's lists. */
+static bool __v4l2_async_notifier_fwnode_has_async_subdev(
+   struct v4l2_async_notifier *notifier, struct fwnode_handle *fwnode)
+{
+   struct v4l2_async_subdev *asd;
+   struct v4l2_subdev *sd;
+
+   list_for_each_entry(asd, >waiting, list) {
+   if (asd->match_type != V4L2_ASYNC_MATCH_FWNODE)
+   continue;
+
+   if (asd->match.fwnode.fwnode == fwnode)
+   return true;
+   }
+
+   list_for_each_entry(sd, >done, async_list) {
+   if (WARN_ON(!sd->asd))
+   continue;
+
+   if (sd->asd->match_type != V4L2_ASYNC_MATCH_FWNODE)
+   continue;
+
+   if (sd->asd->match.fwnode.fwnode == fwnode)
+   return true;
+   }
+
+   return false;
+}
+
+/*
+ * Find out whether an async sub-device was set up for an fwnode already or
+ * whether it exists in a given notifier before @this_index.
+ */
+static bool v4l2_async_notifier_fwnode_has_async_subdev(
+   struct v4l2_async_notifier *notifier, struct fwnode_handle *fwnode,
+   unsigned int this_index)
+{
+   unsigned int j;
+
+   lockdep_assert_held(_lock);
+
+   /* Check that an fwnode is not being added more than once. */
+   for (j = 0; j < this_index; j++) {
+   struct v4l2_async_subdev *asd = notifier->subdevs[this_index];
+   struct v4l2_async_subdev *other_asd = notifier->subdevs[j];
+
+   if (other_asd->match_type == V4L2_ASYNC_MATCH_FWNODE &&
+   asd->match.fwnode.fwnode ==
+   other_asd->match.fwnode.fwnode)
+   return true;
+   }
+
+   /* Check than an fwnode did not exist in other notifiers. */
+   list_for_each_entry(notifier, _list, list)
+   if (__v4l2_async_notifier_fwnode_has_async_subdev(
+   notifier, fwnode))
+   return true;
+
+   return false;
+}
+
 static int __v4l2_async_notifier_register(struct v4l2_async_notifier *notifier)
 {
+   struct device *dev =
+   notifier->v4l2_dev ? notifier->v4l2_dev->dev : NULL;
struct v4l2_async_subdev *asd;
int ret;
int i;
@@ -320,6 +383,8 @@ static int __v4l2_async_notifier_register(struct 
v4l2_async_notifier *notifier)
INIT_LIST_HEAD(>waiting);
INIT_LIST_HEAD(>done);
 
+   mutex_lock(_lock);
+
for (i = 0; i < notifier->num_subdevs; i++) {
asd = notifier->subdevs[i];
 
@@ -327,19 +392,25 @@ static int __v4l2_async_notifier_register(struct 
v4l2_async_notifier *notifier)
case V4L2_ASYNC_MATCH_CUSTOM:
case V4L2_ASYNC_MATCH_DEVNAME:
case V4L2_ASYNC_MATCH_I2C:
+   break;
case V4L2_ASYNC_MATCH_FWNODE:
+   if (v4l2_async_notifier_fwnode_has_async_subdev(
+   notifier, asd->match.fwnode.fwnode, i)) {
+   dev_err(dev,
+   "fwnode has already been registered or 
in notifier's subdev list\n");
+   ret = -EEXIST;
+   goto out_unlock;
+   }
break;
default:
-   dev_err(notifier->v4l2_dev ? notifier->v4l2_dev->dev : 
NULL,
-   "Invalid match type %u on %p\n",
+   dev_err(dev, "Invalid match type %u on %p\n",
asd->match_type, asd);
-   return -EINVAL;
+   ret = -EINVAL;
+   goto out_unlock;
}
list_add_tail(>list, >waiting);
}
 
-   mutex_lock(_lock);
-
ret = v4l2_async_notifier_try_all_subdevs(notifier);
if (ret)
goto err_unbind;
@@ -351,6 +422,7 @@ static int __v4l2_async_notifier_register(struct 
v4l2_async_notifier *notifier)
/* Keep also completed notifiers on the list */
list_add(>list, _list);
 
+out_unlock:

[PATCH v16 10/32] rcar-vin: Use generic parser for parsing fwnode endpoints

2017-10-26 Thread Sakari Ailus
Instead of using a custom 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 
Acked-by: Niklas Söderlund 
---
 drivers/media/platform/rcar-vin/rcar-core.c | 107 +---
 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, 46 insertions(+), 89 deletions(-)

diff --git a/drivers/media/platform/rcar-vin/rcar-core.c 
b/drivers/media/platform/rcar-vin/rcar-core.c
index 142de447..380288658601 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(>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(>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,71 @@ 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), _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 = 

[PATCH v16 08/32] v4l: fwnode: Support generic parsing of graph endpoints in a device

2017-10-26 Thread Sakari Ailus
Add two functions for parsing devices graph endpoints:
v4l2_async_notifier_parse_fwnode_endpoints and
v4l2_async_notifier_parse_fwnode_endpoints_by_port. The former iterates
over all endpoints whereas the latter only iterates over the endpoints in
a given port.

The former is mostly useful for existing drivers that currently implement
the iteration over all the endpoints themselves whereas the latter is
especially intended for devices with both sinks and sources: async
sub-devices for external devices connected to the device's sources will
have already been set up, or the external sub-devices are part of the
master device.

Depends-on: ("device property: preserve usecount for node passed to 
of_fwnode_graph_get_port_parent()")
Signed-off-by: Sakari Ailus 
Acked-by: Hans Verkuil 
---
 drivers/media/v4l2-core/v4l2-async.c  |  31 ++
 drivers/media/v4l2-core/v4l2-fwnode.c | 196 ++
 include/media/v4l2-async.h|  24 -
 include/media/v4l2-fwnode.h   | 118 
 4 files changed, 367 insertions(+), 2 deletions(-)

diff --git a/drivers/media/v4l2-core/v4l2-async.c 
b/drivers/media/v4l2-core/v4l2-async.c
index 8b84fea50c2a..46aebfc75e43 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)
@@ -237,6 +238,36 @@ void v4l2_async_notifier_unregister(struct 
v4l2_async_notifier *notifier)
 }
 EXPORT_SYMBOL(v4l2_async_notifier_unregister);
 
+void v4l2_async_notifier_cleanup(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(true);
+   break;
+   }
+
+   kfree(asd);
+   }
+
+   notifier->max_subdevs = 0;
+   notifier->num_subdevs = 0;
+
+   kvfree(notifier->subdevs);
+   notifier->subdevs = NULL;
+}
+EXPORT_SYMBOL_GPL(v4l2_async_notifier_cleanup);
+
 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 40b2fbfe8865..df0695b7bbcc 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 {
@@ -388,6 +390,200 @@ 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_type = V4L2_ASYNC_MATCH_FWNODE;
+   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;
+   }
+
+   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",
+

[PATCH v16 06/32] v4l: async: Use more intuitive names for internal functions

2017-10-26 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 
Reviewed-by: Sebastian Reichel 
---
 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 cde2cf2ab4b0..8b84fea50c2a 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;
 
@@ -187,11 +187,11 @@ int v4l2_async_notifier_register(struct v4l2_device 
*v4l2_dev,
list_for_each_entry_safe(sd, tmp, _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(_lock);
return ret;
@@ -255,13 +255,14 @@ int v4l2_async_register_subdev(struct v4l2_subdev *sd)
INIT_LIST_HEAD(>async_list);
 
list_for_each_entry(notifier, _list, list) {
-   struct v4l2_async_subdev *asd = v4l2_async_belongs(notifier, 
sd);
+   struct v4l2_async_subdev *asd = v4l2_async_find_match(notifier,
+ sd);
int ret;
 
if (!asd)
continue;
 
-   ret = v4l2_async_test_notify(notifier, sd, asd);
+   ret = v4l2_async_match_notify(notifier, sd, asd);
if (ret)
goto err_unlock;
 
-- 
2.11.0



[PATCH v16 07/32] v4l: async: Add V4L2 async documentation to the documentation build

2017-10-26 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 
Reviewed-by: Sebastian Reichel 
---
 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 v16 12/32] omap3isp: Print the name of the entity where no source pads could be found

2017-10-26 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 4afd7ba4fad6..35687c9707e0 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 v16 14/32] v4l: async: Introduce helpers for calling async ops callbacks

2017-10-26 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 
Acked-by: Pavel Machek 
---
 drivers/media/v4l2-core/v4l2-async.c | 56 +---
 1 file changed, 39 insertions(+), 17 deletions(-)

diff --git a/drivers/media/v4l2-core/v4l2-async.c 
b/drivers/media/v4l2-core/v4l2-async.c
index 9d6fc5f25619..e170682dae78 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;
}
 
@@ -140,8 +165,7 @@ static void v4l2_async_notifier_unbind_all_subdevs(
struct v4l2_subdev *sd, *tmp;
 
list_for_each_entry_safe(sd, tmp, >done, async_list) {
-   if (notifier->ops->unbind)
-   notifier->ops->unbind(notifier, sd, sd->asd);
+   v4l2_async_notifier_call_unbind(notifier, sd, sd->asd);
v4l2_async_cleanup(sd);
 
list_move(>async_list, _list);
@@ -198,8 +222,8 @@ int v4l2_async_notifier_register(struct v4l2_device 
*v4l2_dev,
}
}
 
-   if (list_empty(>waiting) && notifier->ops->complete) {
-   ret = notifier->ops->complete(notifier);
+   if (list_empty(>waiting)) {
+   ret = v4l2_async_notifier_call_complete(notifier);
if (ret)
goto err_complete;
}
@@ -296,10 +320,10 @@ int v4l2_async_register_subdev(struct v4l2_subdev *sd)
if (ret)
goto err_unlock;
 
-   if (!list_empty(>waiting) || !notifier->ops->complete)
+   if (!list_empty(>waiting))
goto out_unlock;
 
-   ret = notifier->ops->complete(notifier);
+   ret = v4l2_async_notifier_call_complete(notifier);
if (ret)
goto err_cleanup;
 
@@ -315,8 +339,7 @@ int v4l2_async_register_subdev(struct v4l2_subdev *sd)
return 0;
 
 err_cleanup:
-   if (notifier->ops->unbind)
-   notifier->ops->unbind(notifier, sd, sd->asd);
+   v4l2_async_notifier_call_unbind(notifier, sd, sd->asd);
v4l2_async_cleanup(sd);
 
 err_unlock:
@@ -335,8 +358,7 @@ void v4l2_async_unregister_subdev(struct v4l2_subdev *sd)
 
list_add(>asd->list, >waiting);
 
-   if (notifier->ops->unbind)
-   notifier->ops->unbind(notifier, sd, sd->asd);
+   v4l2_async_notifier_call_unbind(notifier, sd, sd->asd);
}
 
v4l2_async_cleanup(sd);
-- 
2.11.0



[PATCH v16 16/32] v4l: async: Allow async notifier register call succeed with no subdevs

2017-10-26 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 | 12 ++--
 1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/drivers/media/v4l2-core/v4l2-async.c 
b/drivers/media/v4l2-core/v4l2-async.c
index 46db85685894..1b536d68cedf 100644
--- a/drivers/media/v4l2-core/v4l2-async.c
+++ b/drivers/media/v4l2-core/v4l2-async.c
@@ -180,14 +180,22 @@ int v4l2_async_notifier_register(struct v4l2_device 
*v4l2_dev,
int ret;
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(>waiting);
INIT_LIST_HEAD(>done);
 
+   if (!notifier->num_subdevs) {
+   int ret;
+
+   ret = v4l2_async_notifier_call_complete(notifier);
+   notifier->v4l2_dev = NULL;
+
+   return ret;
+   }
+
for (i = 0; i < notifier->num_subdevs; i++) {
asd = notifier->subdevs[i];
 
-- 
2.11.0



[PATCH v16 11/32] omap3isp: Fix check for our own sub-devices

2017-10-26 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 97a5206b6ddc..4afd7ba4fad6 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, _dev->subdevs, list) {
-   if (!sd->asd)
+   if (sd->notifier != >notifier)
continue;
 
ret = isp_link_entity(isp, >entity,
-- 
2.11.0



[PATCH v16 17/32] v4l: async: Prepare for async sub-device notifiers

2017-10-26 Thread Sakari Ailus
Refactor the V4L2 async framework a little in preparation for async
sub-device notifiers. This avoids making some structural changes in the
patch actually implementing sub-device notifiers, making that patch easier
to review.

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

diff --git a/drivers/media/v4l2-core/v4l2-async.c 
b/drivers/media/v4l2-core/v4l2-async.c
index 1b536d68cedf..eb31d96254d1 100644
--- a/drivers/media/v4l2-core/v4l2-async.c
+++ b/drivers/media/v4l2-core/v4l2-async.c
@@ -125,12 +125,13 @@ static struct v4l2_async_subdev *v4l2_async_find_match(
 }
 
 static int v4l2_async_match_notify(struct v4l2_async_notifier *notifier,
+  struct v4l2_device *v4l2_dev,
   struct v4l2_subdev *sd,
   struct v4l2_async_subdev *asd)
 {
int ret;
 
-   ret = v4l2_device_register_subdev(notifier->v4l2_dev, sd);
+   ret = v4l2_device_register_subdev(v4l2_dev, sd);
if (ret < 0)
return ret;
 
@@ -151,6 +152,31 @@ static int v4l2_async_match_notify(struct 
v4l2_async_notifier *notifier,
return 0;
 }
 
+/* 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_device *v4l2_dev = notifier->v4l2_dev;
+   struct v4l2_subdev *sd, *tmp;
+
+   list_for_each_entry_safe(sd, tmp, _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, v4l2_dev, sd, asd);
+   if (ret < 0) {
+   mutex_unlock(_lock);
+   return ret;
+   }
+   }
+
+   return 0;
+}
+
 static void v4l2_async_cleanup(struct v4l2_subdev *sd)
 {
v4l2_device_unregister_subdev(sd);
@@ -172,18 +198,15 @@ static void v4l2_async_notifier_unbind_all_subdevs(
}
 }
 
-int v4l2_async_notifier_register(struct v4l2_device *v4l2_dev,
-struct v4l2_async_notifier *notifier)
+static int __v4l2_async_notifier_register(struct v4l2_async_notifier *notifier)
 {
-   struct v4l2_subdev *sd, *tmp;
struct v4l2_async_subdev *asd;
int ret;
int i;
 
-   if (!v4l2_dev || notifier->num_subdevs > V4L2_MAX_SUBDEVS)
+   if (notifier->num_subdevs > V4L2_MAX_SUBDEVS)
return -EINVAL;
 
-   notifier->v4l2_dev = v4l2_dev;
INIT_LIST_HEAD(>waiting);
INIT_LIST_HEAD(>done);
 
@@ -216,18 +239,10 @@ int v4l2_async_notifier_register(struct v4l2_device 
*v4l2_dev,
 
mutex_lock(_lock);
 
-   list_for_each_entry_safe(sd, tmp, _list, async_list) {
-   int ret;
-
-   asd = v4l2_async_find_match(notifier, sd);
-   if (!asd)
-   continue;
-
-   ret = v4l2_async_match_notify(notifier, sd, asd);
-   if (ret < 0) {
-   mutex_unlock(_lock);
-   return ret;
-   }
+   ret = v4l2_async_notifier_try_all_subdevs(notifier);
+   if (ret) {
+   mutex_unlock(_lock);
+   return ret;
}
 
if (list_empty(>waiting)) {
@@ -250,6 +265,23 @@ int v4l2_async_notifier_register(struct v4l2_device 
*v4l2_dev,
 
return ret;
 }
+
+int v4l2_async_notifier_register(struct v4l2_device *v4l2_dev,
+struct v4l2_async_notifier *notifier)
+{
+   int ret;
+
+   if (WARN_ON(!v4l2_dev))
+   return -EINVAL;
+
+   notifier->v4l2_dev = v4l2_dev;
+
+   ret = __v4l2_async_notifier_register(notifier);
+   if (ret)
+   notifier->v4l2_dev = NULL;
+
+   return ret;
+}
 EXPORT_SYMBOL(v4l2_async_notifier_register);
 
 void v4l2_async_notifier_unregister(struct v4l2_async_notifier *notifier)
@@ -324,7 +356,8 @@ int v4l2_async_register_subdev(struct v4l2_subdev *sd)
if (!asd)
continue;
 
-   ret = v4l2_async_match_notify(notifier, sd, asd);
+   ret = v4l2_async_match_notify(notifier, notifier->v4l2_dev, sd,
+ asd);
if (ret)
goto err_unlock;
 
-- 
2.11.0



[PATCH v16 05/32] v4l: async: Correctly serialise async sub-device unregistration

2017-10-26 Thread Sakari Ailus
The check whether an async sub-device is bound to a notifier was performed
without list_lock held, making it possible for another process to
unbind the async sub-device before the sub-device unregistration function
proceeds to take the lock.

Fix this by first acquiring the lock and then proceeding with the check.

Signed-off-by: Sakari Ailus 
Reviewed-by: Sebastian Reichel 
Acked-by: Hans Verkuil 
---
 drivers/media/v4l2-core/v4l2-async.c | 18 +++---
 1 file changed, 7 insertions(+), 11 deletions(-)

diff --git a/drivers/media/v4l2-core/v4l2-async.c 
b/drivers/media/v4l2-core/v4l2-async.c
index 4924481451ca..cde2cf2ab4b0 100644
--- a/drivers/media/v4l2-core/v4l2-async.c
+++ b/drivers/media/v4l2-core/v4l2-async.c
@@ -298,20 +298,16 @@ EXPORT_SYMBOL(v4l2_async_register_subdev);
 
 void v4l2_async_unregister_subdev(struct v4l2_subdev *sd)
 {
-   struct v4l2_async_notifier *notifier = sd->notifier;
-
-   if (!sd->asd) {
-   if (!list_empty(>async_list))
-   v4l2_async_cleanup(sd);
-   return;
-   }
-
mutex_lock(_lock);
 
-   list_add(>asd->list, >waiting);
+   if (sd->asd) {
+   struct v4l2_async_notifier *notifier = sd->notifier;
 
-   if (notifier->unbind)
-   notifier->unbind(notifier, sd, sd->asd);
+   list_add(>asd->list, >waiting);
+
+   if (notifier->unbind)
+   notifier->unbind(notifier, sd, sd->asd);
+   }
 
v4l2_async_cleanup(sd);
 
-- 
2.11.0



[PATCH v16 18/32] v4l: async: Allow binding notifiers to sub-devices

2017-10-26 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 complete callback of the root notifier will be called only when the
v4l2_device is available and no notifier has pending sub-devices to bind.
No complete callbacks are supported for sub-device notifiers.

Signed-off-by: Sakari Ailus 
Acked-by: Hans Verkuil 
---
 drivers/media/v4l2-core/v4l2-async.c | 216 ---
 include/media/v4l2-async.h   |  19 ++-
 2 files changed, 190 insertions(+), 45 deletions(-)

diff --git a/drivers/media/v4l2-core/v4l2-async.c 
b/drivers/media/v4l2-core/v4l2-async.c
index eb31d96254d1..ed539c4fd5dc 100644
--- a/drivers/media/v4l2-core/v4l2-async.c
+++ b/drivers/media/v4l2-core/v4l2-async.c
@@ -124,11 +124,87 @@ 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, _list, list)
+   if (n->sd == sd)
+   return n;
+
+   return NULL;
+}
+
+/* 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;
+}
+
+/*
+ * Return true if all child sub-device notifiers are complete, false otherwise.
+ */
+static bool v4l2_async_notifier_can_complete(
+   struct v4l2_async_notifier *notifier)
+{
+   struct v4l2_subdev *sd;
+
+   if (!list_empty(>waiting))
+   return false;
+
+   list_for_each_entry(sd, >done, async_list) {
+   struct v4l2_async_notifier *subdev_notifier =
+   v4l2_async_find_subdev_notifier(sd);
+
+   if (subdev_notifier &&
+   !v4l2_async_notifier_can_complete(subdev_notifier))
+   return false;
+   }
+
+   return true;
+}
+
+/*
+ * Complete the master notifier if possible. This is done when all async
+ * sub-devices have been bound; v4l2_device is also available then.
+ */
+static int v4l2_async_notifier_try_complete(
+   struct v4l2_async_notifier *notifier)
+{
+   /* Quick check whether there are still more sub-devices here. */
+   if (!list_empty(>waiting))
+   return 0;
+
+   /* Check the entire notifier tree; find the root notifier first. */
+   while (notifier->parent)
+   notifier = notifier->parent;
+
+   /* This is root if it has v4l2_dev. */
+   if (!notifier->v4l2_dev)
+   return 0;
+
+   /* Is everything ready? */
+   if (!v4l2_async_notifier_can_complete(notifier))
+   return 0;
+
+   return v4l2_async_notifier_call_complete(notifier);
+}
+
+static int v4l2_async_notifier_try_all_subdevs(
+   struct v4l2_async_notifier *notifier);
+
 static int v4l2_async_match_notify(struct v4l2_async_notifier *notifier,
   struct v4l2_device *v4l2_dev,
   struct v4l2_subdev *sd,
   struct v4l2_async_subdev *asd)
 {
+   struct v4l2_async_notifier *subdev_notifier;
int ret;
 
ret = v4l2_device_register_subdev(v4l2_dev, sd);
@@ -149,17 +225,36 @@ static int v4l2_async_match_notify(struct 
v4l2_async_notifier *notifier,
/* Move from the global subdevice list to notifier's done */
list_move(>async_list, >done);
 
-   return 0;
+   /*
+* See if the sub-device has a notifier. If not, return here.
+*/
+   subdev_notifier = v4l2_async_find_subdev_notifier(sd);
+   if (!subdev_notifier || subdev_notifier->parent)
+   return 0;
+
+   /*
+* Proceed with checking for the sub-device notifier's async
+* sub-devices, and return the result. The error will be handled by the
+* caller.
+*/
+   subdev_notifier->parent = notifier;
+
+   return v4l2_async_notifier_try_all_subdevs(subdev_notifier);
 }
 
 /* Test all async sub-devices in a notifier for a match. */
 static int 

[PATCH v16 03/32] v4l: async: fix unbind error in v4l2_async_notifier_unregister()

2017-10-26 Thread Sakari Ailus
From: Niklas Söderlund 

The call to v4l2_async_cleanup() will set sd->asd to NULL so passing it to
notifier->unbind() has no effect and leaves the notifier confused. Call
the unbind() callback prior to cleaning up the subdevice to avoid this.

Signed-off-by: Niklas Söderlund 
Signed-off-by: Sakari Ailus 
Reviewed-by: Sebastian Reichel 
Acked-by: Hans Verkuil 
---
 drivers/media/v4l2-core/v4l2-async.c | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/media/v4l2-core/v4l2-async.c 
b/drivers/media/v4l2-core/v4l2-async.c
index 21c748bf3a7b..ca281438a0ae 100644
--- a/drivers/media/v4l2-core/v4l2-async.c
+++ b/drivers/media/v4l2-core/v4l2-async.c
@@ -206,11 +206,11 @@ void v4l2_async_notifier_unregister(struct 
v4l2_async_notifier *notifier)
list_del(>list);
 
list_for_each_entry_safe(sd, tmp, >done, async_list) {
-   v4l2_async_cleanup(sd);
-
if (notifier->unbind)
notifier->unbind(notifier, sd, sd->asd);
 
+   v4l2_async_cleanup(sd);
+
list_move(>async_list, _list);
}
 
@@ -268,11 +268,11 @@ void v4l2_async_unregister_subdev(struct v4l2_subdev *sd)
 
list_add(>asd->list, >waiting);
 
-   v4l2_async_cleanup(sd);
-
if (notifier->unbind)
notifier->unbind(notifier, sd, sd->asd);
 
+   v4l2_async_cleanup(sd);
+
mutex_unlock(_lock);
 }
 EXPORT_SYMBOL(v4l2_async_unregister_subdev);
-- 
2.11.0



[PATCH v16 02/32] v4l: async: Don't set sd->dev NULL in v4l2_async_cleanup

2017-10-26 Thread Sakari Ailus
v4l2_async_cleanup() is called when the async sub-device is unbound from
the media device. As the pointer is set by the driver registering the
async sub-device, leave the pointer as set by the driver.

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

diff --git a/drivers/media/v4l2-core/v4l2-async.c 
b/drivers/media/v4l2-core/v4l2-async.c
index 60a1a50b9537..21c748bf3a7b 100644
--- a/drivers/media/v4l2-core/v4l2-async.c
+++ b/drivers/media/v4l2-core/v4l2-async.c
@@ -134,7 +134,6 @@ static void v4l2_async_cleanup(struct v4l2_subdev *sd)
/* Subdevice driver will reprobe and put the subdev back onto the list 
*/
list_del_init(>async_list);
sd->asd = NULL;
-   sd->dev = NULL;
 }
 
 int v4l2_async_notifier_register(struct v4l2_device *v4l2_dev,
-- 
2.11.0



[PATCH v16 09/32] omap3isp: Use generic parser for parsing fwnode endpoints

2017-10-26 Thread Sakari Ailus
Instead of using a custom 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 
Reviewed-by: Laurent Pinchart 
---
 drivers/media/platform/omap3isp/isp.c | 121 +++---
 drivers/media/platform/omap3isp/isp.h |   5 +-
 2 files changed, 40 insertions(+), 86 deletions(-)

diff --git a/drivers/media/platform/omap3isp/isp.c 
b/drivers/media/platform/omap3isp/isp.c
index 1a428fe9f070..97a5206b6ddc 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(>crashed);
+   v4l2_async_notifier_cleanup(>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 = >bus;
-   struct v4l2_fwnode_endpoint vep;
-   unsigned int i;
-   int ret;
bool csi1 = false;
-
-   ret = v4l2_fwnode_endpoint_parse(fwnode, );
-   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",

Re: [GIT PULL for 4.15] More sensor driver patches

2017-10-26 Thread Leon Luo
submitted V9

add an entry in MAINTAINERS
fix a bug in probe
Regards,
Leon Luo
1130 Cadillac CT
Milpitas, CA 95035
Phone: (510)371-1169
Fax: (408) 217-1960
Email: le...@leopardimaging.com
www.leopardimaging.com


On Wed, Oct 25, 2017 at 3:24 AM, Sakari Ailus  wrote:
> On Tue, Oct 17, 2017 at 10:34:06AM +0300, Sakari Ailus wrote:
>> On Mon, Oct 16, 2017 at 05:25:47PM -0700, Leon Luo wrote:
>> > Hi Mauro,
>> >
>> > I am maintaining the driver. I am not sure how to clear this warning
>> > though. If you could shed some light on it, it will be helpful. Thanks.
>>
>> Please add an entry to the MAINTAINERS file. Look for e.g. SMIA for an
>> example.
>
> Ping.
>
> --
> Sakari Ailus
> e-mail: sakari.ai...@iki.fi


Re: [PATCH 0/2] Fix s5p-mfc lock contention in request firmware paths

2017-10-26 Thread Shuah Khan
On 10/25/2017 04:28 PM, Marian Mihailescu wrote:
> Hi Shuah,
> 
> For MFC patch, you can delete the "dev" variable since it's not being
> used anymore and results in a compile warning.
> 
> - struct s5p_mfc_dev *dev = ctx->dev;
> 
> Cheers,
> Marian

Oops. I thought I handled that. I will fix that and resend the patch.

thanks,
-- Shuah


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

2017-10-26 Thread Leon Luo
The binding file for imx274 CMOS sensor V4l2 driver

Signed-off-by: Leon Luo 
Acked-by: Sören Brinkmann 
Acked-by: Rob Herring 
---
v9:
 - add an entry in MAINTAINERS
v8:
 - no changes
v7:
 - no changes
v6:
 - no changes
v5:
 - add 'port' and 'endpoint' information
v4:
 - no changes
v3:
 - remove redundant properties and references
 - document 'reg' property
v2:
 - no changes
---
 .../devicetree/bindings/media/i2c/imx274.txt   | 33 ++
 MAINTAINERS|  8 ++
 2 files changed, 41 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 ..80f2e89568e1
--- /dev/null
+++ b/Documentation/devicetree/bindings/media/i2c/imx274.txt
@@ -0,0 +1,33 @@
+* 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
+
+The imx274 device node should contain one 'port' child node with
+an 'endpoint' subnode. For further reading on port node refer to
+Documentation/devicetree/bindings/media/video-interfaces.txt.
+
+Example:
+   sensor@1a {
+   compatible = "sony,imx274";
+   reg = <0x1a>;
+   #address-cells = <1>;
+   #size-cells = <0>;
+   reset-gpios = <_sensor 0 0>;
+   port {
+   sensor_out: endpoint {
+   remote-endpoint = <_in>;
+   };
+   };
+   };
diff --git a/MAINTAINERS b/MAINTAINERS
index 90230fe020f3..b5927bd4fe1e 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -12486,6 +12486,14 @@ S: Maintained
 F: drivers/ssb/
 F: include/linux/ssb/
 
+SONY IMX274 SENSOR DRIVER
+M: Leon Luo 
+L: linux-media@vger.kernel.org
+T: git git://linuxtv.org/media_tree.git
+S: Maintained
+F: drivers/media/i2c/imx274.c
+F: Documentation/devicetree/bindings/media/i2c/imx274.txt
+
 SONY MEMORYSTICK CARD SUPPORT
 M: Alex Dubov 
 W: http://tifmxx.berlios.de/
-- 
2.14.0.rc1



[PATCH v9 2/2] media:imx274 V4l2 driver for Sony imx274 CMOS sensor

2017-10-26 Thread Leon Luo
The imx274 is a Sony CMOS image sensor that has 1/2.5 image size.
It supports up to 3840x2160 (4K) 60fps, 1080p 120fps. The interface
is 4-lane MIPI CSI-2 running at 1.44Gbps each.

This driver has been tested on Xilinx ZCU102 platform with a Leopard
LI-IMX274MIPI-FMC camera board.

Support for the following features:
-Resolutions: 3840x2160, 1920x1080, 1280x720
-Frame rate: 3840x2160 : 5 – 60fps
1920x1080 : 5 – 120fps
1280x720 : 5 – 120fps
-Exposure time: 16 – (frame interval) micro-seconds
-Gain: 1x - 180x
-VFLIP: enable/disabledrivers/media/i2c/imx274.c
-Test pattern: 12 test patterns

Signed-off-by: Leon Luo 
Tested-by: Sören Brinkmann 
Acked-by: Sakari Ailus 
Acked-by: Chris Kohn 
---
v9:
 - remove v4l2_async_unregister_subdev from probe error
v8:
 - check division by zero error
v7:
 - use __v4l2_ctrl_s_ctrl instead of v4l2_ctrl_s_ctrl to have
   clean mutex_lock/mutex_unlock in imx274_s_stream()
 - define imx274_tp_regs[] as static, move the test pattern reg
   out of imx274_tp_regs[], and define it as a macro
   IMX274_TEST_PATTERN_REG
v6:
 - remove media/v4l2-image-sizes.h from include header
 - make the header file alphabetical order
 - remove fmt->pad check in imx274_get_fmt,
   the V4L2 subdev framework does it already
 - change 'struct reg_8 *regs' to 'struct reg_8 regs[n]',
   where n is the exact numbers needed for this function
 - move MODULE_DEVICE_TABLE(of, imx274_of_id_table); closer
   to imx274_of_id_table definition
 - remove return check of imx274_write_table in imx274_remove,
   because it should remove all resources even i2c fails here
 - move imx274_load_default before v4l2_async_register_subdev
v5:
 - no changes
v4:
 - use 32-bit data type to avoid __divdi3 compile error for i386
 - clean up OR together error codesdrivers/media/i2c/imx274.c
v3:
 - clean up header files
 - use struct directly instead of alias #define
 - use v4l2_ctrl_s_ctrl instead of v4l2_s_ctrl
 - revise debug output
 - move static helpers closer to their call site
 - don't OR toegether error codes
 - use closest valid gain value instead of erroring out
 - assigne lock to the control handler and omit explicit locking
 - acquire mutex lock for imx274_get_fmt
 - remove format->pad check in imx274_set_fmt since the pad is always 0
 - pass struct v4l2_ctrl pointer in gain/exposure/vlip/test pattern controls
 - remove priv->ctrls.vflip->val = val in imx274_set_vflip()
 - remove priv->ctrls.test_pattern->val = val in imx274_set_test_pattern()
 - remove empty open/close callbacks
 - remove empty core ops
 - add more error labels in probe
 - use v4l2_async_unregister_subdev instead of v4l2_device_unregister_subdev
 - use dynamic debug
 - split start_stream to two steps: imx274_mode_regs() and imx274_start_stream()
   frame rate & exposure can be updated
   between imx274_mode_regs() & imx274_start_stream()

v2:
 - Fix Kconfig to not remove existing options
---
 drivers/media/i2c/Kconfig  |7 +
 drivers/media/i2c/Makefile |1 +
 drivers/media/i2c/imx274.c | 1810 
 3 files changed, 1818 insertions(+)
 create mode 100644 drivers/media/i2c/imx274.c

diff --git a/drivers/media/i2c/Kconfig b/drivers/media/i2c/Kconfig
index 47113774a297..9659849e33a0 100644
--- a/drivers/media/i2c/Kconfig
+++ b/drivers/media/i2c/Kconfig
@@ -555,6 +555,13 @@ config VIDEO_APTINA_PLL
 config VIDEO_SMIAPP_PLL
tristate
 
+config VIDEO_IMX274
+   tristate "Sony IMX274 sensor support"
+   depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API
+   ---help---
+ This is a V4L2 sensor-level driver for the Sony IMX274
+ CMOS image sensor.
+
 config VIDEO_OV2640
tristate "OmniVision OV2640 sensor support"
depends on VIDEO_V4L2 && I2C
diff --git a/drivers/media/i2c/Makefile b/drivers/media/i2c/Makefile
index c843c181dfb9..f8d57e453936 100644
--- a/drivers/media/i2c/Makefile
+++ b/drivers/media/i2c/Makefile
@@ -92,5 +92,6 @@ obj-$(CONFIG_VIDEO_IR_I2C)  += ir-kbd-i2c.o
 obj-$(CONFIG_VIDEO_ML86V7667)  += ml86v7667.o
 obj-$(CONFIG_VIDEO_OV2659) += ov2659.o
 obj-$(CONFIG_VIDEO_TC358743)   += tc358743.o
+obj-$(CONFIG_VIDEO_IMX274) += imx274.o
 
 obj-$(CONFIG_SDR_MAX2175) += max2175.o
diff --git a/drivers/media/i2c/imx274.c b/drivers/media/i2c/imx274.c
new file mode 100644
index ..737dbf59a0d2
--- /dev/null
+++ b/drivers/media/i2c/imx274.c
@@ -0,0 +1,1810 @@
+/*
+ * imx274.c - IMX274 CMOS Image Sensor driver
+ *
+ * Copyright (C) 2017, Leopard Imaging, Inc.
+ *
+ * Leon Luo 
+ * Edwin Zou 
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ *