All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v5 00/13] V4L2 Async notifier API cleanup
@ 2021-02-02 13:55 Sakari Ailus
  2021-02-02 13:55 ` [PATCH v5 01/13] media: v4l2-async: Clean v4l2_async_notifier_add_fwnode_remote_subdev Sakari Ailus
                   ` (12 more replies)
  0 siblings, 13 replies; 25+ messages in thread
From: Sakari Ailus @ 2021-02-02 13:55 UTC (permalink / raw)
  To: linux-media
  Cc: Hans Verkuil, kernel, Laurent Pinchart, Kieran Bingham,
	Jacopo Mondi, niklas.soderlund+renesas, Helen Koike,
	Dafna Hirschfeld, Hugues Fruchet, Nicolas Ferre, Yong Zhi,
	Sylwester Nawrocki, Maxime Ripard, Robert Foss, Philipp Zabel,
	Ezequiel Garcia

Hi all,

I took Ezequiel's set (after discussing with him) and made changes on top
of v2 based on the review comments.

The goal of this series is to make the API more consistent,
also fixing all the drivers which are currently misusing the API.

With this change, the v4l2-async functions that add subdevices
to a notifier have the same semantics, that is they all
allocate a struct v4l2_async_subdev, and take a size argument
for drivers to embed struct v4l2_async_subdev in a larger
struct.

This makes the struct v4l2_async_subdev allocation model
more consistent, and simpler to understand.

The V4L2 sub-devices documentation, as well as the kernel-doc
are also improved a bit, clarifying the API.

Finally, all the drivers previously using v4l2_async_notifier_add_subdev
are converted to proper helpers, which allows us to rename
v4l2_async_notifier_add_subdev to __v4l2_async_notifier_add_subdev,
and clarify the documentation so hopefully future drivers
will avoid it.

I have tried to convert the drivers in the least invasive way,
keeping the original code as much as possible. In many cases,
specially the old drivers, there is some bitrot and some room
for more cleanups, which is beyond the scope of this patchset.

The series is now rebased on top of these patches:
media: v4l2-async: Remove V4L2_ASYNC_MATCH_CUSTOM
media: v4l2-async: Remove V4L2_ASYNC_MATCH_DEVNAME
media: pxa_camera: Drop the v4l2-clk clock register
media: imx6-mipi-csi2: Call remote subdev get_mbus_config to get active lanes

Since v4:

- Merge the two async documentation patches; rework documentation a
  little.

- Fix compile error in pxa_camera.c.

- Assign ret in mipi_csis_async_register on error path.

Since v3:

- Forgot to mention rebase on current linux-media master for v3, i.e.
  actually since v2.

- Make the documentation patch last, and adjust it to cover Laurent's
  previously last patch of async API improvements.

- Move async API changes to the right patch (from 11th -> 1st).

- Assign ret in rkisp1_subdev_notifier.

- Use negative error value in
  __v4l2_async_notifier_add_fwnode_remote_subdev.

- Fix functions listed in v4l2_async_notifier_unregister and
  v4l2_async_notifier_register documentation, removing
  v4l2_async_register_subdev_sensor_common and adding
  v4l2_async_notifier_add_fwnode_remote_subdev. I hope this is fine now...

- Fix async API usage and compilation in max9286, rkisp1 and st-mipid02
  driver.

Since v2:

- Don't do useless assign of ret before returning in
  drivers/media/i2c/st-mipid02.c or drivers/media/platform/renesas-ceu.c.

- Don't do of_node_put(NULL) in
  drivers/media/platform/exynos4-is/media-dev.c.

- Fix comment in drivers/media/v4l2-core/v4l2-async.c.

- List all current driver API functions used for working with async
  notifiers in v4l2_async_notifier_init() and
  v4l2_async_notifier_cleanup() kerneldoc documentation in
  include/media/v4l2-async.h.

Changes from v1:
* Add Laurent's follow cleanup, which makes the API safer.
* Fix commit description s/is discouraged/will be discouraged
* Fix missing allocation in renesas-ceu driver.
* Fix missing of_node puts in exynos4-is driver.
* Rework mention of v4l2_fwnode_reference_parse_sensor_common 

Ezequiel Garcia (13):
  media: v4l2-async: Clean v4l2_async_notifier_add_fwnode_remote_subdev
  media: atmel: Use v4l2_async_notifier_add_fwnode_remote_subdev
  media: stm32: Use v4l2_async_notifier_add_fwnode_remote_subdev
  media: exynos4-is: Use v4l2_async_notifier_add_fwnode_remote_subdev
  media: st-mipid02: Use v4l2_async_notifier_add_fwnode_remote_subdev
  media: cadence: Use v4l2_async_notifier_add_fwnode_remote_subdev
  media: marvell-ccic: Use v4l2_async_notifier_add_*_subdev
  media: renesas-ceu: Use v4l2_async_notifier_add_*_subdev
  media: pxa-camera: Use v4l2_async_notifier_add_*_subdev
  media: davinci: vpif_display: Remove unused v4l2-async code
  media: v4l2-async: Fix incorrect comment
  media: v4l2-async: Discourage use of v4l2_async_notifier_add_subdev
  media: Clarify v4l2-async subdevice addition API

Laurent Pinchart (1):
  media: v4l2-async: Improve v4l2_async_notifier_add_*_subdev() API

 .../driver-api/media/v4l2-subdev.rst          | 41 +++++++--
 drivers/media/i2c/max9286.c                   | 14 +--
 drivers/media/i2c/st-mipid02.c                | 21 +++--
 drivers/media/pci/intel/ipu3/ipu3-cio2-main.c | 15 ++--
 drivers/media/platform/am437x/am437x-vpfe.c   |  2 +-
 drivers/media/platform/atmel/atmel-isc.h      |  1 +
 drivers/media/platform/atmel/atmel-isi.c      | 46 +++-------
 .../media/platform/atmel/atmel-sama5d2-isc.c  | 44 ++++------
 drivers/media/platform/cadence/cdns-csi2rx.c  | 17 ++--
 drivers/media/platform/davinci/vpif_capture.c |  2 +-
 drivers/media/platform/davinci/vpif_display.c | 86 ++++--------------
 drivers/media/platform/davinci/vpif_display.h |  1 -
 drivers/media/platform/exynos4-is/media-dev.c | 25 +++---
 drivers/media/platform/exynos4-is/media-dev.h |  2 +-
 .../media/platform/marvell-ccic/cafe-driver.c | 14 ++-
 .../media/platform/marvell-ccic/mcam-core.c   | 10 ---
 .../media/platform/marvell-ccic/mcam-core.h   |  1 -
 .../media/platform/marvell-ccic/mmp-driver.c  | 11 ++-
 drivers/media/platform/omap3isp/isp.c         | 74 ++++++----------
 drivers/media/platform/pxa_camera.c           | 53 +++++------
 drivers/media/platform/qcom/camss/camss.c     | 11 +--
 drivers/media/platform/rcar-vin/rcar-core.c   |  5 +-
 drivers/media/platform/rcar-vin/rcar-csi2.c   |  2 +-
 drivers/media/platform/rcar_drif.c            |  2 +-
 drivers/media/platform/renesas-ceu.c          | 56 +++++-------
 .../platform/rockchip/rkisp1/rkisp1-dev.c     | 15 ++--
 drivers/media/platform/stm32/stm32-dcmi.c     | 87 +++++++------------
 .../platform/sunxi/sun4i-csi/sun4i_csi.c      |  9 +-
 .../platform/sunxi/sun4i-csi/sun4i_csi.h      |  1 -
 drivers/media/platform/ti-vpe/cal.c           | 12 ++-
 drivers/media/platform/video-mux.c            | 14 +--
 drivers/media/platform/xilinx/xilinx-vipp.c   | 10 +--
 drivers/media/v4l2-core/v4l2-async.c          | 54 ++++++------
 drivers/media/v4l2-core/v4l2-fwnode.c         |  6 +-
 drivers/staging/media/imx/imx-media-csi.c     | 14 +--
 drivers/staging/media/imx/imx-media-of.c      |  2 +-
 drivers/staging/media/imx/imx6-mipi-csi2.c    | 19 ++--
 drivers/staging/media/imx/imx7-media-csi.c    | 16 ++--
 drivers/staging/media/imx/imx7-mipi-csis.c    | 15 +---
 drivers/staging/media/tegra-video/vi.c        | 10 +--
 include/media/davinci/vpif_types.h            |  2 -
 include/media/v4l2-async.h                    | 64 +++++++++-----
 42 files changed, 380 insertions(+), 526 deletions(-)

-- 
2.29.2




Ezequiel Garcia (12):
  media: v4l2-async: Clean v4l2_async_notifier_add_fwnode_remote_subdev
  media: atmel: Use v4l2_async_notifier_add_fwnode_remote_subdev
  media: stm32: Use v4l2_async_notifier_add_fwnode_remote_subdev
  media: exynos4-is: Use v4l2_async_notifier_add_fwnode_remote_subdev
  media: st-mipid02: Use v4l2_async_notifier_add_fwnode_remote_subdev
  media: cadence: Use v4l2_async_notifier_add_fwnode_remote_subdev
  media: marvell-ccic: Use v4l2_async_notifier_add_*_subdev
  media: renesas-ceu: Use v4l2_async_notifier_add_*_subdev
  media: pxa-camera: Use v4l2_async_notifier_add_*_subdev
  media: davinci: vpif_display: Remove unused v4l2-async code
  media: v4l2-async: Discourage use of v4l2_async_notifier_add_subdev
  media: Clarify v4l2-async subdevice addition API

Laurent Pinchart (1):
  media: v4l2-async: Improve v4l2_async_notifier_add_*_subdev() API

 .../driver-api/media/v4l2-subdev.rst          | 48 ++++++++--
 drivers/media/i2c/max9286.c                   | 14 +--
 drivers/media/i2c/st-mipid02.c                | 21 +++--
 drivers/media/pci/intel/ipu3/ipu3-cio2-main.c | 15 ++--
 drivers/media/platform/am437x/am437x-vpfe.c   |  2 +-
 drivers/media/platform/atmel/atmel-isc.h      |  1 +
 drivers/media/platform/atmel/atmel-isi.c      | 46 +++-------
 .../media/platform/atmel/atmel-sama5d2-isc.c  | 44 ++++------
 drivers/media/platform/cadence/cdns-csi2rx.c  | 17 ++--
 drivers/media/platform/davinci/vpif_capture.c |  2 +-
 drivers/media/platform/davinci/vpif_display.c | 86 ++++--------------
 drivers/media/platform/davinci/vpif_display.h |  1 -
 drivers/media/platform/exynos4-is/media-dev.c | 25 +++---
 drivers/media/platform/exynos4-is/media-dev.h |  2 +-
 .../media/platform/marvell-ccic/cafe-driver.c | 14 ++-
 .../media/platform/marvell-ccic/mcam-core.c   | 10 ---
 .../media/platform/marvell-ccic/mcam-core.h   |  1 -
 .../media/platform/marvell-ccic/mmp-driver.c  | 11 ++-
 drivers/media/platform/omap3isp/isp.c         | 74 ++++++----------
 drivers/media/platform/pxa_camera.c           | 57 +++++-------
 drivers/media/platform/qcom/camss/camss.c     | 11 +--
 drivers/media/platform/rcar-vin/rcar-core.c   |  5 +-
 drivers/media/platform/rcar-vin/rcar-csi2.c   |  2 +-
 drivers/media/platform/rcar_drif.c            |  2 +-
 drivers/media/platform/renesas-ceu.c          | 56 +++++-------
 .../platform/rockchip/rkisp1/rkisp1-dev.c     | 15 ++--
 drivers/media/platform/stm32/stm32-dcmi.c     | 87 +++++++------------
 .../platform/sunxi/sun4i-csi/sun4i_csi.c      |  9 +-
 .../platform/sunxi/sun4i-csi/sun4i_csi.h      |  1 -
 drivers/media/platform/ti-vpe/cal.c           | 12 ++-
 drivers/media/platform/video-mux.c            | 14 +--
 drivers/media/platform/xilinx/xilinx-vipp.c   | 10 +--
 drivers/media/v4l2-core/v4l2-async.c          | 54 ++++++------
 drivers/media/v4l2-core/v4l2-fwnode.c         |  6 +-
 drivers/staging/media/imx/imx-media-csi.c     | 14 +--
 drivers/staging/media/imx/imx-media-of.c      |  2 +-
 drivers/staging/media/imx/imx6-mipi-csi2.c    | 19 ++--
 drivers/staging/media/imx/imx7-media-csi.c    | 16 ++--
 drivers/staging/media/imx/imx7-mipi-csis.c    | 15 ++--
 drivers/staging/media/tegra-video/vi.c        | 10 +--
 include/media/davinci/vpif_types.h            |  2 -
 include/media/v4l2-async.h                    | 64 +++++++++-----
 42 files changed, 386 insertions(+), 531 deletions(-)

-- 
2.29.2


^ permalink raw reply	[flat|nested] 25+ messages in thread

* [PATCH v5 01/13] media: v4l2-async: Clean v4l2_async_notifier_add_fwnode_remote_subdev
  2021-02-02 13:55 [PATCH v5 00/13] V4L2 Async notifier API cleanup Sakari Ailus
@ 2021-02-02 13:55 ` Sakari Ailus
  2021-02-02 13:56 ` [PATCH v5 02/13] media: atmel: Use v4l2_async_notifier_add_fwnode_remote_subdev Sakari Ailus
                   ` (11 subsequent siblings)
  12 siblings, 0 replies; 25+ messages in thread
From: Sakari Ailus @ 2021-02-02 13:55 UTC (permalink / raw)
  To: linux-media
  Cc: Hans Verkuil, kernel, Laurent Pinchart, Kieran Bingham,
	Jacopo Mondi, niklas.soderlund+renesas, Helen Koike,
	Dafna Hirschfeld, Hugues Fruchet, Nicolas Ferre, Yong Zhi,
	Sylwester Nawrocki, Maxime Ripard, Robert Foss, Philipp Zabel,
	Ezequiel Garcia

From: Ezequiel Garcia <ezequiel@collabora.com>

Change v4l2_async_notifier_add_fwnode_remote_subdev semantics
so it allocates the struct v4l2_async_subdev pointer.

This makes the API consistent: the v4l2-async subdevice addition
functions have now a unified usage model. This model is simpler,
as it makes v4l2-async responsible for the allocation and release
of the subdevice descriptor, and no longer something the driver
has to worry about.

On the user side, the change makes the API simpler for the drivers
to use and less error-prone.

Signed-off-by: Ezequiel Garcia <ezequiel@collabora.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
Reviewed-by: Helen Koike <helen.koike@collabora.com>
---
 drivers/media/pci/intel/ipu3/ipu3-cio2-main.c | 17 ++--
 drivers/media/platform/omap3isp/isp.c         | 79 ++++++++-----------
 .../platform/rockchip/rkisp1/rkisp1-dev.c     | 15 ++--
 .../platform/sunxi/sun4i-csi/sun4i_csi.c      |  9 ++-
 .../platform/sunxi/sun4i-csi/sun4i_csi.h      |  1 -
 drivers/media/platform/video-mux.c            | 14 +---
 drivers/media/v4l2-core/v4l2-async.c          | 24 +++---
 drivers/staging/media/imx/imx-media-csi.c     | 14 +---
 drivers/staging/media/imx/imx6-mipi-csi2.c    | 19 ++---
 drivers/staging/media/imx/imx7-media-csi.c    | 16 ++--
 drivers/staging/media/imx/imx7-mipi-csis.c    | 15 ++--
 include/media/v4l2-async.h                    | 15 ++--
 12 files changed, 96 insertions(+), 142 deletions(-)

diff --git a/drivers/media/pci/intel/ipu3/ipu3-cio2-main.c b/drivers/media/pci/intel/ipu3/ipu3-cio2-main.c
index 3515df50f3e7..8fd311fee4e7 100644
--- a/drivers/media/pci/intel/ipu3/ipu3-cio2-main.c
+++ b/drivers/media/pci/intel/ipu3/ipu3-cio2-main.c
@@ -1464,7 +1464,8 @@ static int cio2_parse_firmware(struct cio2_device *cio2)
 		struct v4l2_fwnode_endpoint vep = {
 			.bus_type = V4L2_MBUS_CSI2_DPHY
 		};
-		struct sensor_async_subdev *s_asd = NULL;
+		struct sensor_async_subdev *s_asd;
+		struct v4l2_async_subdev *asd;
 		struct fwnode_handle *ep;
 
 		ep = fwnode_graph_get_endpoint_by_id(
@@ -1478,27 +1479,23 @@ static int cio2_parse_firmware(struct cio2_device *cio2)
 		if (ret)
 			goto err_parse;
 
-		s_asd = kzalloc(sizeof(*s_asd), GFP_KERNEL);
-		if (!s_asd) {
-			ret = -ENOMEM;
+		asd = v4l2_async_notifier_add_fwnode_remote_subdev(
+				&cio2->notifier, ep, sizeof(*s_asd));
+		if (IS_ERR(asd)) {
+			ret = PTR_ERR(asd);
 			goto err_parse;
 		}
 
+		s_asd = container_of(asd, struct sensor_async_subdev, asd);
 		s_asd->csi2.port = vep.base.port;
 		s_asd->csi2.lanes = vep.bus.mipi_csi2.num_data_lanes;
 
-		ret = v4l2_async_notifier_add_fwnode_remote_subdev(
-			&cio2->notifier, ep, &s_asd->asd);
-		if (ret)
-			goto err_parse;
-
 		fwnode_handle_put(ep);
 
 		continue;
 
 err_parse:
 		fwnode_handle_put(ep);
-		kfree(s_asd);
 		return ret;
 	}
 
diff --git a/drivers/media/platform/omap3isp/isp.c b/drivers/media/platform/omap3isp/isp.c
index b1fc4518e275..1311b4996ece 100644
--- a/drivers/media/platform/omap3isp/isp.c
+++ b/drivers/media/platform/omap3isp/isp.c
@@ -2126,21 +2126,6 @@ static void isp_parse_of_csi1_endpoint(struct device *dev,
 	buscfg->bus.ccp2.crc = 1;
 }
 
-static int isp_alloc_isd(struct isp_async_subdev **isd,
-			 struct isp_bus_cfg **buscfg)
-{
-	struct isp_async_subdev *__isd;
-
-	__isd = kzalloc(sizeof(*__isd), GFP_KERNEL);
-	if (!__isd)
-		return -ENOMEM;
-
-	*isd = __isd;
-	*buscfg = &__isd->bus;
-
-	return 0;
-}
-
 static struct {
 	u32 phy;
 	u32 csi2_if;
@@ -2156,7 +2141,7 @@ static int isp_parse_of_endpoints(struct isp_device *isp)
 {
 	struct fwnode_handle *ep;
 	struct isp_async_subdev *isd = NULL;
-	struct isp_bus_cfg *buscfg;
+	struct v4l2_async_subdev *asd;
 	unsigned int i;
 
 	ep = fwnode_graph_get_endpoint_by_id(
@@ -2174,20 +2159,15 @@ static int isp_parse_of_endpoints(struct isp_device *isp)
 		ret = v4l2_fwnode_endpoint_parse(ep, &vep);
 
 		if (!ret) {
-			ret = isp_alloc_isd(&isd, &buscfg);
-			if (ret)
-				return ret;
-		}
-
-		if (!ret) {
-			isp_parse_of_parallel_endpoint(isp->dev, &vep, buscfg);
-			ret = v4l2_async_notifier_add_fwnode_remote_subdev(
-				&isp->notifier, ep, &isd->asd);
+			asd = v4l2_async_notifier_add_fwnode_remote_subdev(
+				&isp->notifier, ep, sizeof(*isd));
+			if (!IS_ERR(asd)) {
+				isd = container_of(asd, struct isp_async_subdev, asd);
+				isp_parse_of_parallel_endpoint(isp->dev, &vep, &isd->bus);
+			}
 		}
 
 		fwnode_handle_put(ep);
-		if (ret)
-			kfree(isd);
 	}
 
 	for (i = 0; i < ARRAY_SIZE(isp_bus_interfaces); i++) {
@@ -2206,15 +2186,8 @@ static int isp_parse_of_endpoints(struct isp_device *isp)
 		dev_dbg(isp->dev, "parsing serial interface %u, node %pOF\n", i,
 			to_of_node(ep));
 
-		ret = isp_alloc_isd(&isd, &buscfg);
-		if (ret)
-			return ret;
-
 		ret = v4l2_fwnode_endpoint_parse(ep, &vep);
-		if (!ret) {
-			buscfg->interface = isp_bus_interfaces[i].csi2_if;
-			isp_parse_of_csi2_endpoint(isp->dev, &vep, buscfg);
-		} else if (ret == -ENXIO) {
+		if (ret == -ENXIO) {
 			vep = (struct v4l2_fwnode_endpoint)
 				{ .bus_type = V4L2_MBUS_CSI1 };
 			ret = v4l2_fwnode_endpoint_parse(ep, &vep);
@@ -2224,21 +2197,35 @@ static int isp_parse_of_endpoints(struct isp_device *isp)
 					{ .bus_type = V4L2_MBUS_CCP2 };
 				ret = v4l2_fwnode_endpoint_parse(ep, &vep);
 			}
-			if (!ret) {
-				buscfg->interface =
-					isp_bus_interfaces[i].csi1_if;
-				isp_parse_of_csi1_endpoint(isp->dev, &vep,
-							   buscfg);
-			}
 		}
 
-		if (!ret)
-			ret = v4l2_async_notifier_add_fwnode_remote_subdev(
-				&isp->notifier, ep, &isd->asd);
+		if (!ret) {
+			asd = v4l2_async_notifier_add_fwnode_remote_subdev(
+				&isp->notifier, ep, sizeof(*isd));
+
+			if (!IS_ERR(asd)) {
+				isd = container_of(asd, struct isp_async_subdev, asd);
+
+				switch (vep.bus_type) {
+				case V4L2_MBUS_CSI2_DPHY:
+					isd->bus.interface =
+						isp_bus_interfaces[i].csi2_if;
+					isp_parse_of_csi2_endpoint(isp->dev, &vep, &isd->bus);
+					break;
+				case V4L2_MBUS_CSI1:
+				case V4L2_MBUS_CCP2:
+					isd->bus.interface =
+						isp_bus_interfaces[i].csi1_if;
+					isp_parse_of_csi1_endpoint(isp->dev, &vep,
+								   &isd->bus);
+					break;
+				default:
+					break;
+				}
+			}
+		}
 
 		fwnode_handle_put(ep);
-		if (ret)
-			kfree(isd);
 	}
 
 	return 0;
diff --git a/drivers/media/platform/rockchip/rkisp1/rkisp1-dev.c b/drivers/media/platform/rockchip/rkisp1/rkisp1-dev.c
index 68da1eed753d..daa1b6d22436 100644
--- a/drivers/media/platform/rockchip/rkisp1/rkisp1-dev.c
+++ b/drivers/media/platform/rockchip/rkisp1/rkisp1-dev.c
@@ -252,6 +252,7 @@ static int rkisp1_subdev_notifier(struct rkisp1_device *rkisp1)
 			.bus_type = V4L2_MBUS_CSI2_DPHY
 		};
 		struct rkisp1_sensor_async *rk_asd = NULL;
+		struct v4l2_async_subdev *asd;
 		struct fwnode_handle *ep;
 
 		ep = fwnode_graph_get_endpoint_by_id(dev_fwnode(rkisp1->dev),
@@ -264,21 +265,18 @@ static int rkisp1_subdev_notifier(struct rkisp1_device *rkisp1)
 		if (ret)
 			goto err_parse;
 
-		rk_asd = kzalloc(sizeof(*rk_asd), GFP_KERNEL);
-		if (!rk_asd) {
-			ret = -ENOMEM;
+		asd = v4l2_async_notifier_add_fwnode_remote_subdev(ntf, ep,
+							sizeof(*rk_asd));
+		if (IS_ERR(asd)) {
+			ret = PTR_ERR(asd);
 			goto err_parse;
 		}
 
+		rk_asd = container_of(asd, struct rkisp1_sensor_async, asd);
 		rk_asd->mbus_type = vep.bus_type;
 		rk_asd->mbus_flags = vep.bus.mipi_csi2.flags;
 		rk_asd->lanes = vep.bus.mipi_csi2.num_data_lanes;
 
-		ret = v4l2_async_notifier_add_fwnode_remote_subdev(ntf, ep,
-								   &rk_asd->asd);
-		if (ret)
-			goto err_parse;
-
 		dev_dbg(rkisp1->dev, "registered ep id %d with %d lanes\n",
 			vep.base.id, rk_asd->lanes);
 
@@ -289,7 +287,6 @@ static int rkisp1_subdev_notifier(struct rkisp1_device *rkisp1)
 		continue;
 err_parse:
 		fwnode_handle_put(ep);
-		kfree(rk_asd);
 		v4l2_async_notifier_cleanup(ntf);
 		return ret;
 	}
diff --git a/drivers/media/platform/sunxi/sun4i-csi/sun4i_csi.c b/drivers/media/platform/sunxi/sun4i-csi/sun4i_csi.c
index ec46cff80fdb..3f94b8c966f3 100644
--- a/drivers/media/platform/sunxi/sun4i-csi/sun4i_csi.c
+++ b/drivers/media/platform/sunxi/sun4i-csi/sun4i_csi.c
@@ -118,6 +118,7 @@ static int sun4i_csi_notifier_init(struct sun4i_csi *csi)
 	struct v4l2_fwnode_endpoint vep = {
 		.bus_type = V4L2_MBUS_PARALLEL,
 	};
+	struct v4l2_async_subdev *asd;
 	struct fwnode_handle *ep;
 	int ret;
 
@@ -134,10 +135,12 @@ static int sun4i_csi_notifier_init(struct sun4i_csi *csi)
 
 	csi->bus = vep.bus.parallel;
 
-	ret = v4l2_async_notifier_add_fwnode_remote_subdev(&csi->notifier,
-							   ep, &csi->asd);
-	if (ret)
+	asd = v4l2_async_notifier_add_fwnode_remote_subdev(&csi->notifier,
+							   ep, sizeof(*asd));
+	if (IS_ERR(asd)) {
+		ret = PTR_ERR(asd);
 		goto out;
+	}
 
 	csi->notifier.ops = &sun4i_csi_notify_ops;
 
diff --git a/drivers/media/platform/sunxi/sun4i-csi/sun4i_csi.h b/drivers/media/platform/sunxi/sun4i-csi/sun4i_csi.h
index 0f67ff652c2e..a5f61ee0ec4d 100644
--- a/drivers/media/platform/sunxi/sun4i-csi/sun4i_csi.h
+++ b/drivers/media/platform/sunxi/sun4i-csi/sun4i_csi.h
@@ -139,7 +139,6 @@ struct sun4i_csi {
 	struct v4l2_mbus_framefmt	subdev_fmt;
 
 	/* V4L2 Async variables */
-	struct v4l2_async_subdev	asd;
 	struct v4l2_async_notifier	notifier;
 	struct v4l2_subdev		*src_subdev;
 	int				src_pad;
diff --git a/drivers/media/platform/video-mux.c b/drivers/media/platform/video-mux.c
index 53570250a25d..7b280dfca727 100644
--- a/drivers/media/platform/video-mux.c
+++ b/drivers/media/platform/video-mux.c
@@ -370,19 +370,13 @@ static int video_mux_async_register(struct video_mux *vmux,
 		if (!ep)
 			continue;
 
-		asd = kzalloc(sizeof(*asd), GFP_KERNEL);
-		if (!asd) {
-			fwnode_handle_put(ep);
-			return -ENOMEM;
-		}
-
-		ret = v4l2_async_notifier_add_fwnode_remote_subdev(
-			&vmux->notifier, ep, asd);
+		asd = v4l2_async_notifier_add_fwnode_remote_subdev(
+			&vmux->notifier, ep, sizeof(*asd));
 
 		fwnode_handle_put(ep);
 
-		if (ret) {
-			kfree(asd);
+		if (IS_ERR(asd)) {
+			ret = PTR_ERR(asd);
 			/* OK if asd already exists */
 			if (ret != -EEXIST)
 				return ret;
diff --git a/drivers/media/v4l2-core/v4l2-async.c b/drivers/media/v4l2-core/v4l2-async.c
index 221feb9a8f7b..ed603ae63cad 100644
--- a/drivers/media/v4l2-core/v4l2-async.c
+++ b/drivers/media/v4l2-core/v4l2-async.c
@@ -656,26 +656,26 @@ v4l2_async_notifier_add_fwnode_subdev(struct v4l2_async_notifier *notifier,
 }
 EXPORT_SYMBOL_GPL(v4l2_async_notifier_add_fwnode_subdev);
 
-int
+struct v4l2_async_subdev *
 v4l2_async_notifier_add_fwnode_remote_subdev(struct v4l2_async_notifier *notif,
 					     struct fwnode_handle *endpoint,
-					     struct v4l2_async_subdev *asd)
+					     unsigned int asd_struct_size)
 {
+	struct v4l2_async_subdev *asd;
 	struct fwnode_handle *remote;
-	int ret;
 
 	remote = fwnode_graph_get_remote_port_parent(endpoint);
 	if (!remote)
-		return -ENOTCONN;
+		return ERR_PTR(-ENOTCONN);
 
-	asd->match_type = V4L2_ASYNC_MATCH_FWNODE;
-	asd->match.fwnode = remote;
-
-	ret = v4l2_async_notifier_add_subdev(notif, asd);
-	if (ret)
-		fwnode_handle_put(remote);
-
-	return ret;
+	asd = v4l2_async_notifier_add_fwnode_subdev(notif, remote,
+						    asd_struct_size);
+	/*
+	 * Calling v4l2_async_notifier_add_fwnode_subdev grabs a refcount,
+	 * so drop the one we got in fwnode_graph_get_remote_port_parent.
+	 */
+	fwnode_handle_put(remote);
+	return asd;
 }
 EXPORT_SYMBOL_GPL(v4l2_async_notifier_add_fwnode_remote_subdev);
 
diff --git a/drivers/staging/media/imx/imx-media-csi.c b/drivers/staging/media/imx/imx-media-csi.c
index db77fef07654..6344389e6afa 100644
--- a/drivers/staging/media/imx/imx-media-csi.c
+++ b/drivers/staging/media/imx/imx-media-csi.c
@@ -1922,19 +1922,13 @@ static int imx_csi_async_register(struct csi_priv *priv)
 					     port, 0,
 					     FWNODE_GRAPH_ENDPOINT_NEXT);
 	if (ep) {
-		asd = kzalloc(sizeof(*asd), GFP_KERNEL);
-		if (!asd) {
-			fwnode_handle_put(ep);
-			return -ENOMEM;
-		}
-
-		ret = v4l2_async_notifier_add_fwnode_remote_subdev(
-			&priv->notifier, ep, asd);
+		asd = v4l2_async_notifier_add_fwnode_remote_subdev(
+			&priv->notifier, ep, sizeof(*asd));
 
 		fwnode_handle_put(ep);
 
-		if (ret) {
-			kfree(asd);
+		if (IS_ERR(asd)) {
+			ret = PTR_ERR(asd);
 			/* OK if asd already exists */
 			if (ret != -EEXIST)
 				return ret;
diff --git a/drivers/staging/media/imx/imx6-mipi-csi2.c b/drivers/staging/media/imx/imx6-mipi-csi2.c
index 6b58899dcefe..a79ab38158e2 100644
--- a/drivers/staging/media/imx/imx6-mipi-csi2.c
+++ b/drivers/staging/media/imx/imx6-mipi-csi2.c
@@ -641,7 +641,7 @@ static int csi2_async_register(struct csi2_dev *csi2)
 	struct v4l2_fwnode_endpoint vep = {
 		.bus_type = V4L2_MBUS_CSI2_DPHY,
 	};
-	struct v4l2_async_subdev *asd = NULL;
+	struct v4l2_async_subdev *asd;
 	struct fwnode_handle *ep;
 	int ret;
 
@@ -661,19 +661,13 @@ static int csi2_async_register(struct csi2_dev *csi2)
 	dev_dbg(csi2->dev, "data lanes: %d\n", vep.bus.mipi_csi2.num_data_lanes);
 	dev_dbg(csi2->dev, "flags: 0x%08x\n", vep.bus.mipi_csi2.flags);
 
-	asd = kzalloc(sizeof(*asd), GFP_KERNEL);
-	if (!asd) {
-		ret = -ENOMEM;
-		goto err_parse;
-	}
-
-	ret = v4l2_async_notifier_add_fwnode_remote_subdev(
-		&csi2->notifier, ep, asd);
-	if (ret)
-		goto err_parse;
-
+	asd = v4l2_async_notifier_add_fwnode_remote_subdev(
+		&csi2->notifier, ep, sizeof(*asd));
 	fwnode_handle_put(ep);
 
+	if (IS_ERR(asd))
+		return PTR_ERR(asd);
+
 	csi2->notifier.ops = &csi2_notify_ops;
 
 	ret = v4l2_async_subdev_notifier_register(&csi2->sd,
@@ -685,7 +679,6 @@ static int csi2_async_register(struct csi2_dev *csi2)
 
 err_parse:
 	fwnode_handle_put(ep);
-	kfree(asd);
 	return ret;
 }
 
diff --git a/drivers/staging/media/imx/imx7-media-csi.c b/drivers/staging/media/imx/imx7-media-csi.c
index ac52b1daf991..6c59485291ca 100644
--- a/drivers/staging/media/imx/imx7-media-csi.c
+++ b/drivers/staging/media/imx/imx7-media-csi.c
@@ -1191,7 +1191,7 @@ static const struct v4l2_async_notifier_operations imx7_csi_notify_ops = {
 
 static int imx7_csi_async_register(struct imx7_csi *csi)
 {
-	struct v4l2_async_subdev *asd = NULL;
+	struct v4l2_async_subdev *asd;
 	struct fwnode_handle *ep;
 	int ret;
 
@@ -1200,19 +1200,13 @@ static int imx7_csi_async_register(struct imx7_csi *csi)
 	ep = fwnode_graph_get_endpoint_by_id(dev_fwnode(csi->dev), 0, 0,
 					     FWNODE_GRAPH_ENDPOINT_NEXT);
 	if (ep) {
-		asd = kzalloc(sizeof(*asd), GFP_KERNEL);
-		if (!asd) {
-			fwnode_handle_put(ep);
-			return -ENOMEM;
-		}
-
-		ret = v4l2_async_notifier_add_fwnode_remote_subdev(
-			&csi->notifier, ep, asd);
+		asd = v4l2_async_notifier_add_fwnode_remote_subdev(
+			&csi->notifier, ep, sizeof(*asd));
 
 		fwnode_handle_put(ep);
 
-		if (ret) {
-			kfree(asd);
+		if (IS_ERR(asd)) {
+			ret = PTR_ERR(asd);
 			/* OK if asd already exists */
 			if (ret != -EEXIST)
 				return ret;
diff --git a/drivers/staging/media/imx/imx7-mipi-csis.c b/drivers/staging/media/imx/imx7-mipi-csis.c
index 7612993cc1d6..1ba77e629e5b 100644
--- a/drivers/staging/media/imx/imx7-mipi-csis.c
+++ b/drivers/staging/media/imx/imx7-mipi-csis.c
@@ -1004,7 +1004,7 @@ static int mipi_csis_async_register(struct csi_state *state)
 	struct v4l2_fwnode_endpoint vep = {
 		.bus_type = V4L2_MBUS_CSI2_DPHY,
 	};
-	struct v4l2_async_subdev *asd = NULL;
+	struct v4l2_async_subdev *asd;
 	struct fwnode_handle *ep;
 	int ret;
 
@@ -1024,17 +1024,13 @@ static int mipi_csis_async_register(struct csi_state *state)
 	dev_dbg(state->dev, "data lanes: %d\n", state->bus.num_data_lanes);
 	dev_dbg(state->dev, "flags: 0x%08x\n", state->bus.flags);
 
-	asd = kzalloc(sizeof(*asd), GFP_KERNEL);
-	if (!asd) {
-		ret = -ENOMEM;
+	asd = v4l2_async_notifier_add_fwnode_remote_subdev(
+		&state->notifier, ep, sizeof(*asd));
+	if (IS_ERR(asd)) {
+		ret = PTR_ERR(asd);
 		goto err_parse;
 	}
 
-	ret = v4l2_async_notifier_add_fwnode_remote_subdev(
-		&state->notifier, ep, asd);
-	if (ret)
-		goto err_parse;
-
 	fwnode_handle_put(ep);
 
 	state->notifier.ops = &mipi_csis_notify_ops;
@@ -1048,7 +1044,6 @@ static int mipi_csis_async_register(struct csi_state *state)
 
 err_parse:
 	fwnode_handle_put(ep);
-	kfree(asd);
 
 	return ret;
 }
diff --git a/include/media/v4l2-async.h b/include/media/v4l2-async.h
index 0ddc06e36c08..8815e233677e 100644
--- a/include/media/v4l2-async.h
+++ b/include/media/v4l2-async.h
@@ -174,9 +174,11 @@ v4l2_async_notifier_add_fwnode_subdev(struct v4l2_async_notifier *notifier,
  *
  * @notif: pointer to &struct v4l2_async_notifier
  * @endpoint: local endpoint pointing to the remote sub-device to be matched
- * @asd: Async sub-device struct allocated by the caller. The &struct
- *	 v4l2_async_subdev shall be the first member of the driver's async
- *	 sub-device struct, i.e. both begin at the same memory address.
+ * @asd_struct_size: size of the driver's async sub-device struct, including
+ *		     sizeof(struct v4l2_async_subdev). The &struct
+ *		     v4l2_async_subdev shall be the first member of
+ *		     the driver's async sub-device struct, i.e. both
+ *		     begin at the same memory address.
  *
  * Gets the remote endpoint of a given local endpoint, set it up for fwnode
  * matching and adds the async sub-device to the notifier's @asd_list. The
@@ -184,13 +186,12 @@ v4l2_async_notifier_add_fwnode_subdev(struct v4l2_async_notifier *notifier,
  * notifier cleanup time.
  *
  * This is just like @v4l2_async_notifier_add_fwnode_subdev, but with the
- * exception that the fwnode refers to a local endpoint, not the remote one, and
- * the function relies on the caller to allocate the async sub-device struct.
+ * exception that the fwnode refers to a local endpoint, not the remote one.
  */
-int
+struct v4l2_async_subdev *
 v4l2_async_notifier_add_fwnode_remote_subdev(struct v4l2_async_notifier *notif,
 					     struct fwnode_handle *endpoint,
-					     struct v4l2_async_subdev *asd);
+					     unsigned int asd_struct_size);
 
 /**
  * v4l2_async_notifier_add_i2c_subdev - Allocate and add an i2c async
-- 
2.29.2


^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCH v5 02/13] media: atmel: Use v4l2_async_notifier_add_fwnode_remote_subdev
  2021-02-02 13:55 [PATCH v5 00/13] V4L2 Async notifier API cleanup Sakari Ailus
  2021-02-02 13:55 ` [PATCH v5 01/13] media: v4l2-async: Clean v4l2_async_notifier_add_fwnode_remote_subdev Sakari Ailus
@ 2021-02-02 13:56 ` Sakari Ailus
  2021-02-02 13:56 ` [PATCH v5 03/13] media: stm32: " Sakari Ailus
                   ` (10 subsequent siblings)
  12 siblings, 0 replies; 25+ messages in thread
From: Sakari Ailus @ 2021-02-02 13:56 UTC (permalink / raw)
  To: linux-media
  Cc: Hans Verkuil, kernel, Laurent Pinchart, Kieran Bingham,
	Jacopo Mondi, niklas.soderlund+renesas, Helen Koike,
	Dafna Hirschfeld, Hugues Fruchet, Nicolas Ferre, Yong Zhi,
	Sylwester Nawrocki, Maxime Ripard, Robert Foss, Philipp Zabel,
	Ezequiel Garcia

From: Ezequiel Garcia <ezequiel@collabora.com>

The use of v4l2_async_notifier_add_subdev will be discouraged.
Drivers are instead encouraged to use a helper such as
v4l2_async_notifier_add_fwnode_remote_subdev.

This fixes a misuse of the API, as v4l2_async_notifier_add_subdev
should get a kmalloc'ed struct v4l2_async_subdev,
removing some boilerplate code while at it.

Signed-off-by: Ezequiel Garcia <ezequiel@collabora.com>
Reviewed-by: Jacopo Mondi <jacopo+renesas@jmondi.org>
Reviewed-by: Helen Koike <helen.koike@collabora.com>
Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
---
 drivers/media/platform/atmel/atmel-isc.h      |  1 +
 drivers/media/platform/atmel/atmel-isi.c      | 46 ++++++-------------
 .../media/platform/atmel/atmel-sama5d2-isc.c  | 44 ++++++------------
 3 files changed, 29 insertions(+), 62 deletions(-)

diff --git a/drivers/media/platform/atmel/atmel-isc.h b/drivers/media/platform/atmel/atmel-isc.h
index 24b784b893d6..fab8eca58d93 100644
--- a/drivers/media/platform/atmel/atmel-isc.h
+++ b/drivers/media/platform/atmel/atmel-isc.h
@@ -41,6 +41,7 @@ struct isc_buffer {
 struct isc_subdev_entity {
 	struct v4l2_subdev		*sd;
 	struct v4l2_async_subdev	*asd;
+	struct device_node		*epn;
 	struct v4l2_async_notifier      notifier;
 
 	u32 pfe_cfg0;
diff --git a/drivers/media/platform/atmel/atmel-isi.c b/drivers/media/platform/atmel/atmel-isi.c
index d74aa73f26be..c1a6dd7af002 100644
--- a/drivers/media/platform/atmel/atmel-isi.c
+++ b/drivers/media/platform/atmel/atmel-isi.c
@@ -70,7 +70,6 @@ struct frame_buffer {
 struct isi_graph_entity {
 	struct device_node *node;
 
-	struct v4l2_async_subdev asd;
 	struct v4l2_subdev *subdev;
 };
 
@@ -1136,45 +1135,26 @@ static const struct v4l2_async_notifier_operations isi_graph_notify_ops = {
 	.complete = isi_graph_notify_complete,
 };
 
-static int isi_graph_parse(struct atmel_isi *isi, struct device_node *node)
-{
-	struct device_node *ep = NULL;
-	struct device_node *remote;
-
-	ep = of_graph_get_next_endpoint(node, ep);
-	if (!ep)
-		return -EINVAL;
-
-	remote = of_graph_get_remote_port_parent(ep);
-	of_node_put(ep);
-	if (!remote)
-		return -EINVAL;
-
-	/* Remote node to connect */
-	isi->entity.node = remote;
-	isi->entity.asd.match_type = V4L2_ASYNC_MATCH_FWNODE;
-	isi->entity.asd.match.fwnode = of_fwnode_handle(remote);
-	return 0;
-}
-
 static int isi_graph_init(struct atmel_isi *isi)
 {
+	struct v4l2_async_subdev *asd;
+	struct device_node *ep;
 	int ret;
 
-	/* Parse the graph to extract a list of subdevice DT nodes. */
-	ret = isi_graph_parse(isi, isi->dev->of_node);
-	if (ret < 0) {
-		dev_err(isi->dev, "Graph parsing failed\n");
-		return ret;
-	}
+	ep = of_graph_get_next_endpoint(isi->dev->of_node, NULL);
+	if (!ep)
+		return -EINVAL;
 
 	v4l2_async_notifier_init(&isi->notifier);
 
-	ret = v4l2_async_notifier_add_subdev(&isi->notifier, &isi->entity.asd);
-	if (ret) {
-		of_node_put(isi->entity.node);
-		return ret;
-	}
+	asd = v4l2_async_notifier_add_fwnode_remote_subdev(
+						&isi->notifier,
+						of_fwnode_handle(ep),
+						sizeof(*asd));
+	of_node_put(ep);
+
+	if (IS_ERR(asd))
+		return PTR_ERR(asd);
 
 	isi->notifier.ops = &isi_graph_notify_ops;
 
diff --git a/drivers/media/platform/atmel/atmel-sama5d2-isc.c b/drivers/media/platform/atmel/atmel-sama5d2-isc.c
index a3304f49e499..9ee2cd194f93 100644
--- a/drivers/media/platform/atmel/atmel-sama5d2-isc.c
+++ b/drivers/media/platform/atmel/atmel-sama5d2-isc.c
@@ -57,7 +57,7 @@
 static int isc_parse_dt(struct device *dev, struct isc_device *isc)
 {
 	struct device_node *np = dev->of_node;
-	struct device_node *epn = NULL, *rem;
+	struct device_node *epn = NULL;
 	struct isc_subdev_entity *subdev_entity;
 	unsigned int flags;
 	int ret;
@@ -71,17 +71,9 @@ static int isc_parse_dt(struct device *dev, struct isc_device *isc)
 		if (!epn)
 			return 0;
 
-		rem = of_graph_get_remote_port_parent(epn);
-		if (!rem) {
-			dev_notice(dev, "Remote device at %pOF not found\n",
-				   epn);
-			continue;
-		}
-
 		ret = v4l2_fwnode_endpoint_parse(of_fwnode_handle(epn),
 						 &v4l2_epn);
 		if (ret) {
-			of_node_put(rem);
 			ret = -EINVAL;
 			dev_err(dev, "Could not parse the endpoint\n");
 			break;
@@ -90,21 +82,10 @@ static int isc_parse_dt(struct device *dev, struct isc_device *isc)
 		subdev_entity = devm_kzalloc(dev, sizeof(*subdev_entity),
 					     GFP_KERNEL);
 		if (!subdev_entity) {
-			of_node_put(rem);
-			ret = -ENOMEM;
-			break;
-		}
-
-		/* asd will be freed by the subsystem once it's added to the
-		 * notifier list
-		 */
-		subdev_entity->asd = kzalloc(sizeof(*subdev_entity->asd),
-					     GFP_KERNEL);
-		if (!subdev_entity->asd) {
-			of_node_put(rem);
 			ret = -ENOMEM;
 			break;
 		}
+		subdev_entity->epn = epn;
 
 		flags = v4l2_epn.bus.parallel.flags;
 
@@ -121,12 +102,10 @@ static int isc_parse_dt(struct device *dev, struct isc_device *isc)
 			subdev_entity->pfe_cfg0 |= ISC_PFE_CFG0_CCIR_CRC |
 					ISC_PFE_CFG0_CCIR656;
 
-		subdev_entity->asd->match_type = V4L2_ASYNC_MATCH_FWNODE;
-		subdev_entity->asd->match.fwnode = of_fwnode_handle(rem);
 		list_add_tail(&subdev_entity->list, &isc->subdev_entities);
 	}
-
 	of_node_put(epn);
+
 	return ret;
 }
 
@@ -228,13 +207,20 @@ static int atmel_isc_probe(struct platform_device *pdev)
 	}
 
 	list_for_each_entry(subdev_entity, &isc->subdev_entities, list) {
+		struct v4l2_async_subdev *asd;
+
 		v4l2_async_notifier_init(&subdev_entity->notifier);
 
-		ret = v4l2_async_notifier_add_subdev(&subdev_entity->notifier,
-						     subdev_entity->asd);
-		if (ret) {
-			fwnode_handle_put(subdev_entity->asd->match.fwnode);
-			kfree(subdev_entity->asd);
+		asd = v4l2_async_notifier_add_fwnode_remote_subdev(
+					&subdev_entity->notifier,
+					of_fwnode_handle(subdev_entity->epn),
+					sizeof(*asd));
+
+		of_node_put(subdev_entity->epn);
+		subdev_entity->epn = NULL;
+
+		if (IS_ERR(asd)) {
+			ret = PTR_ERR(asd);
 			goto cleanup_subdev;
 		}
 
-- 
2.29.2


^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCH v5 03/13] media: stm32: Use v4l2_async_notifier_add_fwnode_remote_subdev
  2021-02-02 13:55 [PATCH v5 00/13] V4L2 Async notifier API cleanup Sakari Ailus
  2021-02-02 13:55 ` [PATCH v5 01/13] media: v4l2-async: Clean v4l2_async_notifier_add_fwnode_remote_subdev Sakari Ailus
  2021-02-02 13:56 ` [PATCH v5 02/13] media: atmel: Use v4l2_async_notifier_add_fwnode_remote_subdev Sakari Ailus
@ 2021-02-02 13:56 ` Sakari Ailus
  2021-02-02 13:56 ` [PATCH v5 04/13] media: exynos4-is: " Sakari Ailus
                   ` (9 subsequent siblings)
  12 siblings, 0 replies; 25+ messages in thread
From: Sakari Ailus @ 2021-02-02 13:56 UTC (permalink / raw)
  To: linux-media
  Cc: Hans Verkuil, kernel, Laurent Pinchart, Kieran Bingham,
	Jacopo Mondi, niklas.soderlund+renesas, Helen Koike,
	Dafna Hirschfeld, Hugues Fruchet, Nicolas Ferre, Yong Zhi,
	Sylwester Nawrocki, Maxime Ripard, Robert Foss, Philipp Zabel,
	Ezequiel Garcia

From: Ezequiel Garcia <ezequiel@collabora.com>

The use of v4l2_async_notifier_add_subdev will be discouraged.
Drivers are instead encouraged to use a helper such as
v4l2_async_notifier_add_fwnode_remote_subdev.

This fixes a misuse of the API, as v4l2_async_notifier_add_subdev
should get a kmalloc'ed struct v4l2_async_subdev,
removing some boilerplate code while at it.

Use the appropriate helper v4l2_async_notifier_add_fwnode_remote_subdev,
which handles the needed setup, instead of open-coding it.

This results in removal of the now unneeded driver-specific state
struct dcmi_graph_entity, keeping track of just the source
subdevice.

Signed-off-by: Ezequiel Garcia <ezequiel@collabora.com>
Reviewed-by: Jacopo Mondi <jacopo+renesas@jmondi.org>
Reviewed-by: Helen Koike <helen.koike@collabora.com>
Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
---
 drivers/media/platform/stm32/stm32-dcmi.c | 86 ++++++++---------------
 1 file changed, 30 insertions(+), 56 deletions(-)

diff --git a/drivers/media/platform/stm32/stm32-dcmi.c b/drivers/media/platform/stm32/stm32-dcmi.c
index b745f1342c2e..142f63d07dcd 100644
--- a/drivers/media/platform/stm32/stm32-dcmi.c
+++ b/drivers/media/platform/stm32/stm32-dcmi.c
@@ -99,13 +99,6 @@ enum state {
 
 #define OVERRUN_ERROR_THRESHOLD	3
 
-struct dcmi_graph_entity {
-	struct v4l2_async_subdev asd;
-
-	struct device_node *remote_node;
-	struct v4l2_subdev *source;
-};
-
 struct dcmi_format {
 	u32	fourcc;
 	u32	mbus_code;
@@ -139,7 +132,7 @@ struct stm32_dcmi {
 	struct v4l2_device		v4l2_dev;
 	struct video_device		*vdev;
 	struct v4l2_async_notifier	notifier;
-	struct dcmi_graph_entity	entity;
+	struct v4l2_subdev		*source;
 	struct v4l2_format		fmt;
 	struct v4l2_rect		crop;
 	bool				do_crop;
@@ -610,7 +603,7 @@ static int dcmi_pipeline_s_fmt(struct stm32_dcmi *dcmi,
 			       struct v4l2_subdev_pad_config *pad_cfg,
 			       struct v4l2_subdev_format *format)
 {
-	struct media_entity *entity = &dcmi->entity.source->entity;
+	struct media_entity *entity = &dcmi->source->entity;
 	struct v4l2_subdev *subdev;
 	struct media_pad *sink_pad = NULL;
 	struct media_pad *src_pad = NULL;
@@ -1018,7 +1011,7 @@ static int dcmi_try_fmt(struct stm32_dcmi *dcmi, struct v4l2_format *f,
 	}
 
 	v4l2_fill_mbus_format(&format.format, pix, sd_fmt->mbus_code);
-	ret = v4l2_subdev_call(dcmi->entity.source, pad, set_fmt,
+	ret = v4l2_subdev_call(dcmi->source, pad, set_fmt,
 			       &pad_cfg, &format);
 	if (ret < 0)
 		return ret;
@@ -1152,7 +1145,7 @@ static int dcmi_get_sensor_format(struct stm32_dcmi *dcmi,
 	};
 	int ret;
 
-	ret = v4l2_subdev_call(dcmi->entity.source, pad, get_fmt, NULL, &fmt);
+	ret = v4l2_subdev_call(dcmi->source, pad, get_fmt, NULL, &fmt);
 	if (ret)
 		return ret;
 
@@ -1181,7 +1174,7 @@ static int dcmi_set_sensor_format(struct stm32_dcmi *dcmi,
 	}
 
 	v4l2_fill_mbus_format(&format.format, pix, sd_fmt->mbus_code);
-	ret = v4l2_subdev_call(dcmi->entity.source, pad, set_fmt,
+	ret = v4l2_subdev_call(dcmi->source, pad, set_fmt,
 			       &pad_cfg, &format);
 	if (ret < 0)
 		return ret;
@@ -1204,7 +1197,7 @@ static int dcmi_get_sensor_bounds(struct stm32_dcmi *dcmi,
 	/*
 	 * Get sensor bounds first
 	 */
-	ret = v4l2_subdev_call(dcmi->entity.source, pad, get_selection,
+	ret = v4l2_subdev_call(dcmi->source, pad, get_selection,
 			       NULL, &bounds);
 	if (!ret)
 		*r = bounds.r;
@@ -1385,7 +1378,7 @@ static int dcmi_enum_framesizes(struct file *file, void *fh,
 
 	fse.code = sd_fmt->mbus_code;
 
-	ret = v4l2_subdev_call(dcmi->entity.source, pad, enum_frame_size,
+	ret = v4l2_subdev_call(dcmi->source, pad, enum_frame_size,
 			       NULL, &fse);
 	if (ret)
 		return ret;
@@ -1402,7 +1395,7 @@ static int dcmi_g_parm(struct file *file, void *priv,
 {
 	struct stm32_dcmi *dcmi = video_drvdata(file);
 
-	return v4l2_g_parm_cap(video_devdata(file), dcmi->entity.source, p);
+	return v4l2_g_parm_cap(video_devdata(file), dcmi->source, p);
 }
 
 static int dcmi_s_parm(struct file *file, void *priv,
@@ -1410,7 +1403,7 @@ static int dcmi_s_parm(struct file *file, void *priv,
 {
 	struct stm32_dcmi *dcmi = video_drvdata(file);
 
-	return v4l2_s_parm_cap(video_devdata(file), dcmi->entity.source, p);
+	return v4l2_s_parm_cap(video_devdata(file), dcmi->source, p);
 }
 
 static int dcmi_enum_frameintervals(struct file *file, void *fh,
@@ -1432,7 +1425,7 @@ static int dcmi_enum_frameintervals(struct file *file, void *fh,
 
 	fie.code = sd_fmt->mbus_code;
 
-	ret = v4l2_subdev_call(dcmi->entity.source, pad,
+	ret = v4l2_subdev_call(dcmi->source, pad,
 			       enum_frame_interval, NULL, &fie);
 	if (ret)
 		return ret;
@@ -1452,7 +1445,7 @@ MODULE_DEVICE_TABLE(of, stm32_dcmi_of_match);
 static int dcmi_open(struct file *file)
 {
 	struct stm32_dcmi *dcmi = video_drvdata(file);
-	struct v4l2_subdev *sd = dcmi->entity.source;
+	struct v4l2_subdev *sd = dcmi->source;
 	int ret;
 
 	if (mutex_lock_interruptible(&dcmi->lock))
@@ -1483,7 +1476,7 @@ static int dcmi_open(struct file *file)
 static int dcmi_release(struct file *file)
 {
 	struct stm32_dcmi *dcmi = video_drvdata(file);
-	struct v4l2_subdev *sd = dcmi->entity.source;
+	struct v4l2_subdev *sd = dcmi->source;
 	bool fh_singular;
 	int ret;
 
@@ -1616,7 +1609,7 @@ static int dcmi_formats_init(struct stm32_dcmi *dcmi)
 {
 	const struct dcmi_format *sd_fmts[ARRAY_SIZE(dcmi_formats)];
 	unsigned int num_fmts = 0, i, j;
-	struct v4l2_subdev *subdev = dcmi->entity.source;
+	struct v4l2_subdev *subdev = dcmi->source;
 	struct v4l2_subdev_mbus_code_enum mbus_code = {
 		.which = V4L2_SUBDEV_FORMAT_ACTIVE,
 	};
@@ -1675,7 +1668,7 @@ static int dcmi_formats_init(struct stm32_dcmi *dcmi)
 static int dcmi_framesizes_init(struct stm32_dcmi *dcmi)
 {
 	unsigned int num_fsize = 0;
-	struct v4l2_subdev *subdev = dcmi->entity.source;
+	struct v4l2_subdev *subdev = dcmi->source;
 	struct v4l2_subdev_frame_size_enum fse = {
 		.which = V4L2_SUBDEV_FORMAT_ACTIVE,
 		.code = dcmi->sd_format->mbus_code,
@@ -1727,14 +1720,13 @@ static int dcmi_graph_notify_complete(struct v4l2_async_notifier *notifier)
 	 * we search for the source subdevice
 	 * in order to expose it through V4L2 interface
 	 */
-	dcmi->entity.source =
-		media_entity_to_v4l2_subdev(dcmi_find_source(dcmi));
-	if (!dcmi->entity.source) {
+	dcmi->source = media_entity_to_v4l2_subdev(dcmi_find_source(dcmi));
+	if (!dcmi->source) {
 		dev_err(dcmi->dev, "Source subdevice not found\n");
 		return -ENODEV;
 	}
 
-	dcmi->vdev->ctrl_handler = dcmi->entity.source->ctrl_handler;
+	dcmi->vdev->ctrl_handler = dcmi->source->ctrl_handler;
 
 	ret = dcmi_formats_init(dcmi);
 	if (ret) {
@@ -1813,46 +1805,28 @@ static const struct v4l2_async_notifier_operations dcmi_graph_notify_ops = {
 	.complete = dcmi_graph_notify_complete,
 };
 
-static int dcmi_graph_parse(struct stm32_dcmi *dcmi, struct device_node *node)
-{
-	struct device_node *ep = NULL;
-	struct device_node *remote;
-
-	ep = of_graph_get_next_endpoint(node, ep);
-	if (!ep)
-		return -EINVAL;
-
-	remote = of_graph_get_remote_port_parent(ep);
-	of_node_put(ep);
-	if (!remote)
-		return -EINVAL;
-
-	/* Remote node to connect */
-	dcmi->entity.remote_node = remote;
-	dcmi->entity.asd.match_type = V4L2_ASYNC_MATCH_FWNODE;
-	dcmi->entity.asd.match.fwnode = of_fwnode_handle(remote);
-	return 0;
-}
-
 static int dcmi_graph_init(struct stm32_dcmi *dcmi)
 {
+	struct v4l2_async_subdev *asd;
+	struct device_node *ep;
 	int ret;
 
-	/* Parse the graph to extract a list of subdevice DT nodes. */
-	ret = dcmi_graph_parse(dcmi, dcmi->dev->of_node);
-	if (ret < 0) {
-		dev_err(dcmi->dev, "Failed to parse graph\n");
-		return ret;
+	ep = of_graph_get_next_endpoint(dcmi->dev->of_node, NULL);
+	if (!ep) {
+		dev_err(dcmi->dev, "Failed to get next endpoint\n");
+		return -EINVAL;
 	}
 
 	v4l2_async_notifier_init(&dcmi->notifier);
 
-	ret = v4l2_async_notifier_add_subdev(&dcmi->notifier,
-					     &dcmi->entity.asd);
-	if (ret) {
+	asd = v4l2_async_notifier_add_fwnode_remote_subdev(
+		&dcmi->notifier, of_fwnode_handle(ep), sizeof(*asd));
+
+	of_node_put(ep);
+
+	if (IS_ERR(asd)) {
 		dev_err(dcmi->dev, "Failed to add subdev notifier\n");
-		of_node_put(dcmi->entity.remote_node);
-		return ret;
+		return PTR_ERR(asd);
 	}
 
 	dcmi->notifier.ops = &dcmi_graph_notify_ops;
-- 
2.29.2


^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCH v5 04/13] media: exynos4-is: Use v4l2_async_notifier_add_fwnode_remote_subdev
  2021-02-02 13:55 [PATCH v5 00/13] V4L2 Async notifier API cleanup Sakari Ailus
                   ` (2 preceding siblings ...)
  2021-02-02 13:56 ` [PATCH v5 03/13] media: stm32: " Sakari Ailus
@ 2021-02-02 13:56 ` Sakari Ailus
  2021-02-02 13:56 ` [PATCH v5 05/13] media: st-mipid02: " Sakari Ailus
                   ` (8 subsequent siblings)
  12 siblings, 0 replies; 25+ messages in thread
From: Sakari Ailus @ 2021-02-02 13:56 UTC (permalink / raw)
  To: linux-media
  Cc: Hans Verkuil, kernel, Laurent Pinchart, Kieran Bingham,
	Jacopo Mondi, niklas.soderlund+renesas, Helen Koike,
	Dafna Hirschfeld, Hugues Fruchet, Nicolas Ferre, Yong Zhi,
	Sylwester Nawrocki, Maxime Ripard, Robert Foss, Philipp Zabel,
	Ezequiel Garcia

From: Ezequiel Garcia <ezequiel@collabora.com>

The use of v4l2_async_notifier_add_subdev will be discouraged.
Drivers are instead encouraged to use a helper such as
v4l2_async_notifier_add_fwnode_remote_subdev.

This fixes a misuse of the API, as v4l2_async_notifier_add_subdev
should get a kmalloc'ed struct v4l2_async_subdev,
removing some boilerplate code while at it.

Use the appropriate helper v4l2_async_notifier_add_fwnode_remote_subdev,
which handles the needed setup, instead of open-coding it.

Signed-off-by: Ezequiel Garcia <ezequiel@collabora.com>
Reviewed-by: Jacopo Mondi <jacopo+renesas@jmondi.org>
Reviewed-by: Helen Koike <helen.koike@collabora.com>
Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
---
 drivers/media/platform/exynos4-is/media-dev.c | 24 ++++++++++---------
 drivers/media/platform/exynos4-is/media-dev.h |  2 +-
 2 files changed, 14 insertions(+), 12 deletions(-)

diff --git a/drivers/media/platform/exynos4-is/media-dev.c b/drivers/media/platform/exynos4-is/media-dev.c
index e636c33e847b..f4687b0cbd65 100644
--- a/drivers/media/platform/exynos4-is/media-dev.c
+++ b/drivers/media/platform/exynos4-is/media-dev.c
@@ -401,6 +401,7 @@ static int fimc_md_parse_one_endpoint(struct fimc_md *fmd,
 	int index = fmd->num_sensors;
 	struct fimc_source_info *pd = &fmd->sensor[index].pdata;
 	struct device_node *rem, *np;
+	struct v4l2_async_subdev *asd;
 	struct v4l2_fwnode_endpoint endpoint = { .bus_type = 0 };
 	int ret;
 
@@ -418,10 +419,10 @@ static int fimc_md_parse_one_endpoint(struct fimc_md *fmd,
 	pd->mux_id = (endpoint.base.port - 1) & 0x1;
 
 	rem = of_graph_get_remote_port_parent(ep);
-	of_node_put(ep);
 	if (rem == NULL) {
 		v4l2_info(&fmd->v4l2_dev, "Remote device at %pOF not found\n",
 							ep);
+		of_node_put(ep);
 		return 0;
 	}
 
@@ -450,6 +451,7 @@ static int fimc_md_parse_one_endpoint(struct fimc_md *fmd,
 	 * checking parent's node name.
 	 */
 	np = of_get_parent(rem);
+	of_node_put(rem);
 
 	if (of_node_name_eq(np, "i2c-isp"))
 		pd->fimc_bus_type = FIMC_BUS_TYPE_ISP_WRITEBACK;
@@ -458,20 +460,19 @@ static int fimc_md_parse_one_endpoint(struct fimc_md *fmd,
 	of_node_put(np);
 
 	if (WARN_ON(index >= ARRAY_SIZE(fmd->sensor))) {
-		of_node_put(rem);
+		of_node_put(ep);
 		return -EINVAL;
 	}
 
-	fmd->sensor[index].asd.match_type = V4L2_ASYNC_MATCH_FWNODE;
-	fmd->sensor[index].asd.match.fwnode = of_fwnode_handle(rem);
+	asd = v4l2_async_notifier_add_fwnode_remote_subdev(
+		&fmd->subdev_notifier, of_fwnode_handle(ep), sizeof(*asd));
 
-	ret = v4l2_async_notifier_add_subdev(&fmd->subdev_notifier,
-					     &fmd->sensor[index].asd);
-	if (ret) {
-		of_node_put(rem);
-		return ret;
-	}
+	of_node_put(ep);
+
+	if (IS_ERR(asd))
+		return PTR_ERR(asd);
 
+	fmd->sensor[index].asd = asd;
 	fmd->num_sensors++;
 
 	return 0;
@@ -1381,7 +1382,8 @@ static int subdev_notifier_bound(struct v4l2_async_notifier *notifier,
 
 	/* Find platform data for this sensor subdev */
 	for (i = 0; i < ARRAY_SIZE(fmd->sensor); i++)
-		if (fmd->sensor[i].asd.match.fwnode ==
+		if (fmd->sensor[i].asd &&
+		    fmd->sensor[i].asd->match.fwnode ==
 		    of_fwnode_handle(subdev->dev->of_node))
 			si = &fmd->sensor[i];
 
diff --git a/drivers/media/platform/exynos4-is/media-dev.h b/drivers/media/platform/exynos4-is/media-dev.h
index 9447fafe23c6..a3876d668ea6 100644
--- a/drivers/media/platform/exynos4-is/media-dev.h
+++ b/drivers/media/platform/exynos4-is/media-dev.h
@@ -83,7 +83,7 @@ struct fimc_camclk_info {
  */
 struct fimc_sensor_info {
 	struct fimc_source_info pdata;
-	struct v4l2_async_subdev asd;
+	struct v4l2_async_subdev *asd;
 	struct v4l2_subdev *subdev;
 	struct fimc_dev *host;
 };
-- 
2.29.2


^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCH v5 05/13] media: st-mipid02: Use v4l2_async_notifier_add_fwnode_remote_subdev
  2021-02-02 13:55 [PATCH v5 00/13] V4L2 Async notifier API cleanup Sakari Ailus
                   ` (3 preceding siblings ...)
  2021-02-02 13:56 ` [PATCH v5 04/13] media: exynos4-is: " Sakari Ailus
@ 2021-02-02 13:56 ` Sakari Ailus
  2021-02-02 13:56 ` [PATCH v5 06/13] media: cadence: " Sakari Ailus
                   ` (7 subsequent siblings)
  12 siblings, 0 replies; 25+ messages in thread
From: Sakari Ailus @ 2021-02-02 13:56 UTC (permalink / raw)
  To: linux-media
  Cc: Hans Verkuil, kernel, Laurent Pinchart, Kieran Bingham,
	Jacopo Mondi, niklas.soderlund+renesas, Helen Koike,
	Dafna Hirschfeld, Hugues Fruchet, Nicolas Ferre, Yong Zhi,
	Sylwester Nawrocki, Maxime Ripard, Robert Foss, Philipp Zabel,
	Ezequiel Garcia

From: Ezequiel Garcia <ezequiel@collabora.com>

The use of v4l2_async_notifier_add_subdev will be discouraged.
Drivers are instead encouraged to use a helper such as
v4l2_async_notifier_add_fwnode_remote_subdev.

This fixes a misuse of the API, as v4l2_async_notifier_add_subdev
should get a kmalloc'ed struct v4l2_async_subdev,
removing some boilerplate code while at it.

Use the appropriate helper v4l2_async_notifier_add_fwnode_remote_subdev,
which handles the needed setup, instead of open-coding it.

Signed-off-by: Ezequiel Garcia <ezequiel@collabora.com>
Reviewed-by: Jacopo Mondi <jacopo+renesas@jmondi.org>
Reviewed-by: Helen Koike <helen.koike@collabora.com>
Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
---
 drivers/media/i2c/st-mipid02.c | 21 ++++++++++-----------
 1 file changed, 10 insertions(+), 11 deletions(-)

diff --git a/drivers/media/i2c/st-mipid02.c b/drivers/media/i2c/st-mipid02.c
index 003ba22334cd..bb32a5278a4e 100644
--- a/drivers/media/i2c/st-mipid02.c
+++ b/drivers/media/i2c/st-mipid02.c
@@ -92,7 +92,6 @@ struct mipid02_dev {
 	u64 link_frequency;
 	struct v4l2_fwnode_endpoint tx;
 	/* remote source */
-	struct v4l2_async_subdev asd;
 	struct v4l2_async_notifier notifier;
 	struct v4l2_subdev *s_subdev;
 	/* registers */
@@ -844,6 +843,7 @@ static int mipid02_parse_rx_ep(struct mipid02_dev *bridge)
 {
 	struct v4l2_fwnode_endpoint ep = { .bus_type = V4L2_MBUS_CSI2_DPHY };
 	struct i2c_client *client = bridge->i2c_client;
+	struct v4l2_async_subdev *asd;
 	struct device_node *ep_node;
 	int ret;
 
@@ -875,18 +875,17 @@ static int mipid02_parse_rx_ep(struct mipid02_dev *bridge)
 	bridge->rx = ep;
 
 	/* register async notifier so we get noticed when sensor is connected */
-	bridge->asd.match.fwnode =
-		fwnode_graph_get_remote_port_parent(of_fwnode_handle(ep_node));
-	bridge->asd.match_type = V4L2_ASYNC_MATCH_FWNODE;
+	v4l2_async_notifier_init(&bridge->notifier);
+	asd = v4l2_async_notifier_add_fwnode_remote_subdev(
+					&bridge->notifier,
+					of_fwnode_handle(ep_node),
+					sizeof(*asd));
 	of_node_put(ep_node);
 
-	v4l2_async_notifier_init(&bridge->notifier);
-	ret = v4l2_async_notifier_add_subdev(&bridge->notifier, &bridge->asd);
-	if (ret) {
-		dev_err(&client->dev, "fail to register asd to notifier %d",
-			ret);
-		fwnode_handle_put(bridge->asd.match.fwnode);
-		return ret;
+	if (IS_ERR(asd)) {
+		dev_err(&client->dev, "fail to register asd to notifier %ld",
+			PTR_ERR(asd));
+		return PTR_ERR(asd);
 	}
 	bridge->notifier.ops = &mipid02_notifier_ops;
 
-- 
2.29.2


^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCH v5 06/13] media: cadence: Use v4l2_async_notifier_add_fwnode_remote_subdev
  2021-02-02 13:55 [PATCH v5 00/13] V4L2 Async notifier API cleanup Sakari Ailus
                   ` (4 preceding siblings ...)
  2021-02-02 13:56 ` [PATCH v5 05/13] media: st-mipid02: " Sakari Ailus
@ 2021-02-02 13:56 ` Sakari Ailus
  2021-02-02 13:56 ` [PATCH v5 07/13] media: marvell-ccic: Use v4l2_async_notifier_add_*_subdev Sakari Ailus
                   ` (6 subsequent siblings)
  12 siblings, 0 replies; 25+ messages in thread
From: Sakari Ailus @ 2021-02-02 13:56 UTC (permalink / raw)
  To: linux-media
  Cc: Hans Verkuil, kernel, Laurent Pinchart, Kieran Bingham,
	Jacopo Mondi, niklas.soderlund+renesas, Helen Koike,
	Dafna Hirschfeld, Hugues Fruchet, Nicolas Ferre, Yong Zhi,
	Sylwester Nawrocki, Maxime Ripard, Robert Foss, Philipp Zabel,
	Ezequiel Garcia

From: Ezequiel Garcia <ezequiel@collabora.com>

The use of v4l2_async_notifier_add_subdev will be discouraged.
Drivers are instead encouraged to use a helper such as
v4l2_async_notifier_add_fwnode_remote_subdev.

This fixes a misuse of the API, as v4l2_async_notifier_add_subdev
should get a kmalloc'ed struct v4l2_async_subdev,
removing some boilerplate code while at it.

Use the appropriate helper v4l2_async_notifier_add_fwnode_remote_subdev,
which handles the needed setup, instead of open-coding it.

Signed-off-by: Ezequiel Garcia <ezequiel@collabora.com>
Reviewed-by: Jacopo Mondi <jacopo+renesas@jmondi.org>
Reviewed-by: Helen Koike <helen.koike@collabora.com>
Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
---
 drivers/media/platform/cadence/cdns-csi2rx.c | 16 ++++++----------
 1 file changed, 6 insertions(+), 10 deletions(-)

diff --git a/drivers/media/platform/cadence/cdns-csi2rx.c b/drivers/media/platform/cadence/cdns-csi2rx.c
index be9ec59774d6..7d299cacef8c 100644
--- a/drivers/media/platform/cadence/cdns-csi2rx.c
+++ b/drivers/media/platform/cadence/cdns-csi2rx.c
@@ -81,7 +81,6 @@ struct csi2rx_priv {
 	struct media_pad		pads[CSI2RX_PAD_MAX];
 
 	/* Remote source */
-	struct v4l2_async_subdev	asd;
 	struct v4l2_subdev		*source_subdev;
 	int				source_pad;
 };
@@ -362,6 +361,7 @@ static int csi2rx_get_resources(struct csi2rx_priv *csi2rx,
 static int csi2rx_parse_dt(struct csi2rx_priv *csi2rx)
 {
 	struct v4l2_fwnode_endpoint v4l2_ep = { .bus_type = 0 };
+	struct v4l2_async_subdev *asd;
 	struct fwnode_handle *fwh;
 	struct device_node *ep;
 	int ret;
@@ -395,17 +395,13 @@ static int csi2rx_parse_dt(struct csi2rx_priv *csi2rx)
 		return -EINVAL;
 	}
 
-	csi2rx->asd.match.fwnode = fwnode_graph_get_remote_port_parent(fwh);
-	csi2rx->asd.match_type = V4L2_ASYNC_MATCH_FWNODE;
-	of_node_put(ep);
-
 	v4l2_async_notifier_init(&csi2rx->notifier);
 
-	ret = v4l2_async_notifier_add_subdev(&csi2rx->notifier, &csi2rx->asd);
-	if (ret) {
-		fwnode_handle_put(csi2rx->asd.match.fwnode);
-		return ret;
-	}
+	asd = v4l2_async_notifier_add_fwnode_remote_subdev(&csi2rx->notifier,
+							   fwh, sizeof(*asd));
+	of_node_put(ep);
+	if (IS_ERR(asd))
+		return PTR_ERR(asd);
 
 	csi2rx->notifier.ops = &csi2rx_notifier_ops;
 
-- 
2.29.2


^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCH v5 07/13] media: marvell-ccic: Use v4l2_async_notifier_add_*_subdev
  2021-02-02 13:55 [PATCH v5 00/13] V4L2 Async notifier API cleanup Sakari Ailus
                   ` (5 preceding siblings ...)
  2021-02-02 13:56 ` [PATCH v5 06/13] media: cadence: " Sakari Ailus
@ 2021-02-02 13:56 ` Sakari Ailus
  2021-02-02 13:56 ` [PATCH v5 08/13] media: renesas-ceu: " Sakari Ailus
                   ` (5 subsequent siblings)
  12 siblings, 0 replies; 25+ messages in thread
From: Sakari Ailus @ 2021-02-02 13:56 UTC (permalink / raw)
  To: linux-media
  Cc: Hans Verkuil, kernel, Laurent Pinchart, Kieran Bingham,
	Jacopo Mondi, niklas.soderlund+renesas, Helen Koike,
	Dafna Hirschfeld, Hugues Fruchet, Nicolas Ferre, Yong Zhi,
	Sylwester Nawrocki, Maxime Ripard, Robert Foss, Philipp Zabel,
	Ezequiel Garcia

From: Ezequiel Garcia <ezequiel@collabora.com>

The use of v4l2_async_notifier_add_subdev will be discouraged.
Drivers are instead encouraged to use a helper such as
v4l2_async_notifier_add_fwnode_remote_subdev.

This fixes a misuse of the API, as v4l2_async_notifier_add_subdev
should get a kmalloc'ed struct v4l2_async_subdev,
removing some boilerplate code while at it.

Use the appropriate helper: v4l2_async_notifier_add_i2c_subdev
or v4l2_async_notifier_add_fwnode_remote_subdev, which handles
the needed setup, instead of open-coding it.

Signed-off-by: Ezequiel Garcia <ezequiel@collabora.com>
Reviewed-by: Jacopo Mondi <jacopo+renesas@jmondi.org>
Reviewed-by: Helen Koike <helen.koike@collabora.com>
Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
---
 drivers/media/platform/marvell-ccic/cafe-driver.c | 14 +++++++++++---
 drivers/media/platform/marvell-ccic/mcam-core.c   | 10 ----------
 drivers/media/platform/marvell-ccic/mcam-core.h   |  1 -
 drivers/media/platform/marvell-ccic/mmp-driver.c  | 11 ++++++++---
 4 files changed, 19 insertions(+), 17 deletions(-)

diff --git a/drivers/media/platform/marvell-ccic/cafe-driver.c b/drivers/media/platform/marvell-ccic/cafe-driver.c
index 00f623d62c96..91d65f71be96 100644
--- a/drivers/media/platform/marvell-ccic/cafe-driver.c
+++ b/drivers/media/platform/marvell-ccic/cafe-driver.c
@@ -489,6 +489,7 @@ static int cafe_pci_probe(struct pci_dev *pdev,
 	int ret;
 	struct cafe_camera *cam;
 	struct mcam_camera *mcam;
+	struct v4l2_async_subdev *asd;
 
 	/*
 	 * Start putting together one of our big camera structures.
@@ -546,9 +547,16 @@ static int cafe_pci_probe(struct pci_dev *pdev,
 	if (ret)
 		goto out_pdown;
 
-	mcam->asd.match_type = V4L2_ASYNC_MATCH_I2C;
-	mcam->asd.match.i2c.adapter_id = i2c_adapter_id(cam->i2c_adapter);
-	mcam->asd.match.i2c.address = ov7670_info.addr;
+	v4l2_async_notifier_init(&mcam->notifier);
+
+	asd = v4l2_async_notifier_add_i2c_subdev(&mcam->notifier,
+					i2c_adapter_id(cam->i2c_adapter),
+					ov7670_info.addr,
+					sizeof(*asd));
+	if (IS_ERR(asd)) {
+		ret = PTR_ERR(asd);
+		goto out_smbus_shutdown;
+	}
 
 	ret = mccic_register(mcam);
 	if (ret)
diff --git a/drivers/media/platform/marvell-ccic/mcam-core.c b/drivers/media/platform/marvell-ccic/mcam-core.c
index c012fd2e1d29..153277e4fe80 100644
--- a/drivers/media/platform/marvell-ccic/mcam-core.c
+++ b/drivers/media/platform/marvell-ccic/mcam-core.c
@@ -1866,16 +1866,6 @@ int mccic_register(struct mcam_camera *cam)
 	cam->pix_format = mcam_def_pix_format;
 	cam->mbus_code = mcam_def_mbus_code;
 
-	/*
-	 * Register sensor notifier.
-	 */
-	v4l2_async_notifier_init(&cam->notifier);
-	ret = v4l2_async_notifier_add_subdev(&cam->notifier, &cam->asd);
-	if (ret) {
-		cam_warn(cam, "failed to add subdev to a notifier");
-		goto out;
-	}
-
 	cam->notifier.ops = &mccic_notify_ops;
 	ret = v4l2_async_notifier_register(&cam->v4l2_dev, &cam->notifier);
 	if (ret < 0) {
diff --git a/drivers/media/platform/marvell-ccic/mcam-core.h b/drivers/media/platform/marvell-ccic/mcam-core.h
index b55545822fd2..f324d808d737 100644
--- a/drivers/media/platform/marvell-ccic/mcam-core.h
+++ b/drivers/media/platform/marvell-ccic/mcam-core.h
@@ -151,7 +151,6 @@ struct mcam_camera {
 	 */
 	struct video_device vdev;
 	struct v4l2_async_notifier notifier;
-	struct v4l2_async_subdev asd;
 	struct v4l2_subdev *sensor;
 
 	/* Videobuf2 stuff */
diff --git a/drivers/media/platform/marvell-ccic/mmp-driver.c b/drivers/media/platform/marvell-ccic/mmp-driver.c
index 032fdddbbecc..40d9fc4a731a 100644
--- a/drivers/media/platform/marvell-ccic/mmp-driver.c
+++ b/drivers/media/platform/marvell-ccic/mmp-driver.c
@@ -180,6 +180,7 @@ static int mmpcam_probe(struct platform_device *pdev)
 	struct resource *res;
 	struct fwnode_handle *ep;
 	struct mmp_camera_platform_data *pdata;
+	struct v4l2_async_subdev *asd;
 	int ret;
 
 	cam = devm_kzalloc(&pdev->dev, sizeof(*cam), GFP_KERNEL);
@@ -238,10 +239,15 @@ static int mmpcam_probe(struct platform_device *pdev)
 	if (!ep)
 		return -ENODEV;
 
-	mcam->asd.match_type = V4L2_ASYNC_MATCH_FWNODE;
-	mcam->asd.match.fwnode = fwnode_graph_get_remote_port_parent(ep);
+	v4l2_async_notifier_init(&mcam->notifier);
 
+	asd = v4l2_async_notifier_add_fwnode_remote_subdev(&mcam->notifier,
+							   ep, sizeof(*asd));
 	fwnode_handle_put(ep);
+	if (IS_ERR(asd)) {
+		ret = PTR_ERR(asd);
+		goto out;
+	}
 
 	/*
 	 * Register the device with the core.
@@ -278,7 +284,6 @@ static int mmpcam_probe(struct platform_device *pdev)
 	pm_runtime_enable(&pdev->dev);
 	return 0;
 out:
-	fwnode_handle_put(mcam->asd.match.fwnode);
 	mccic_shutdown(mcam);
 
 	return ret;
-- 
2.29.2


^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCH v5 08/13] media: renesas-ceu: Use v4l2_async_notifier_add_*_subdev
  2021-02-02 13:55 [PATCH v5 00/13] V4L2 Async notifier API cleanup Sakari Ailus
                   ` (6 preceding siblings ...)
  2021-02-02 13:56 ` [PATCH v5 07/13] media: marvell-ccic: Use v4l2_async_notifier_add_*_subdev Sakari Ailus
@ 2021-02-02 13:56 ` Sakari Ailus
  2021-02-02 13:56 ` [PATCH v5 09/13] media: pxa-camera: " Sakari Ailus
                   ` (4 subsequent siblings)
  12 siblings, 0 replies; 25+ messages in thread
From: Sakari Ailus @ 2021-02-02 13:56 UTC (permalink / raw)
  To: linux-media
  Cc: Hans Verkuil, kernel, Laurent Pinchart, Kieran Bingham,
	Jacopo Mondi, niklas.soderlund+renesas, Helen Koike,
	Dafna Hirschfeld, Hugues Fruchet, Nicolas Ferre, Yong Zhi,
	Sylwester Nawrocki, Maxime Ripard, Robert Foss, Philipp Zabel,
	Ezequiel Garcia

From: Ezequiel Garcia <ezequiel@collabora.com>

The use of v4l2_async_notifier_add_subdev will be discouraged.
Drivers are instead encouraged to use a helper such as
v4l2_async_notifier_add_i2c_subdev.

This fixes a misuse of the API, as v4l2_async_notifier_add_subdev
should get a kmalloc'ed struct v4l2_async_subdev,
removing some boilerplate code while at it.

Use the appropriate helper: v4l2_async_notifier_add_i2c_subdev
or v4l2_async_notifier_add_fwnode_remote_subdev, which handles
the needed setup, instead of open-coding it.

Using v4l2-async to allocate the driver-specific structs,
requires to change struct ceu_subdev so the embedded
struct v4l2_async_subdev is now the first element.

Signed-off-by: Ezequiel Garcia <ezequiel@collabora.com>
Reviewed-by: Jacopo Mondi <jacopo+renesas@jmondi.org>
Reviewed-by: Helen Koike <helen.koike@collabora.com>
Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
---
 drivers/media/platform/renesas-ceu.c | 60 +++++++++++++---------------
 1 file changed, 27 insertions(+), 33 deletions(-)

diff --git a/drivers/media/platform/renesas-ceu.c b/drivers/media/platform/renesas-ceu.c
index 4a633ad0e8fa..0298d08b39e4 100644
--- a/drivers/media/platform/renesas-ceu.c
+++ b/drivers/media/platform/renesas-ceu.c
@@ -152,8 +152,8 @@ static inline struct ceu_buffer *vb2_to_ceu(struct vb2_v4l2_buffer *vbuf)
  * ceu_subdev - Wraps v4l2 sub-device and provides async subdevice.
  */
 struct ceu_subdev {
-	struct v4l2_subdev *v4l2_sd;
 	struct v4l2_async_subdev asd;
+	struct v4l2_subdev *v4l2_sd;
 
 	/* per-subdevice mbus configuration options */
 	unsigned int mbus_flags;
@@ -174,7 +174,7 @@ struct ceu_device {
 	struct v4l2_device	v4l2_dev;
 
 	/* subdevices descriptors */
-	struct ceu_subdev	*subdevs;
+	struct ceu_subdev	**subdevs;
 	/* the subdevice currently in use */
 	struct ceu_subdev	*sd;
 	unsigned int		sd_index;
@@ -1195,7 +1195,7 @@ static int ceu_enum_input(struct file *file, void *priv,
 	if (inp->index >= ceudev->num_sd)
 		return -EINVAL;
 
-	ceusd = &ceudev->subdevs[inp->index];
+	ceusd = ceudev->subdevs[inp->index];
 
 	inp->type = V4L2_INPUT_TYPE_CAMERA;
 	inp->std = 0;
@@ -1230,7 +1230,7 @@ static int ceu_s_input(struct file *file, void *priv, unsigned int i)
 		return 0;
 
 	ceu_sd_old = ceudev->sd;
-	ceudev->sd = &ceudev->subdevs[i];
+	ceudev->sd = ceudev->subdevs[i];
 
 	/*
 	 * Make sure we can generate output image formats and apply
@@ -1423,7 +1423,7 @@ static int ceu_notify_complete(struct v4l2_async_notifier *notifier)
 	 * ceu formats.
 	 */
 	if (!ceudev->sd) {
-		ceudev->sd = &ceudev->subdevs[0];
+		ceudev->sd = ceudev->subdevs[0];
 		ceudev->sd_index = 0;
 	}
 
@@ -1467,8 +1467,8 @@ static const struct v4l2_async_notifier_operations ceu_notify_ops = {
 
 /*
  * ceu_init_async_subdevs() - Initialize CEU subdevices and async_subdevs in
- *			      ceu device. Both DT and platform data parsing use
- *			      this routine.
+ *                           ceu device. Both DT and platform data parsing use
+ *                           this routine.
  *
  * Returns 0 for success, -ENOMEM for failure.
  */
@@ -1495,6 +1495,7 @@ static int ceu_parse_platform_data(struct ceu_device *ceudev,
 				   const struct ceu_platform_data *pdata)
 {
 	const struct ceu_async_subdev *async_sd;
+	struct v4l2_async_subdev *asd;
 	struct ceu_subdev *ceu_sd;
 	unsigned int i;
 	int ret;
@@ -1510,21 +1511,17 @@ static int ceu_parse_platform_data(struct ceu_device *ceudev,
 
 		/* Setup the ceu subdevice and the async subdevice. */
 		async_sd = &pdata->subdevs[i];
-		ceu_sd = &ceudev->subdevs[i];
-
-		INIT_LIST_HEAD(&ceu_sd->asd.list);
-
-		ceu_sd->mbus_flags	= async_sd->flags;
-		ceu_sd->asd.match_type	= V4L2_ASYNC_MATCH_I2C;
-		ceu_sd->asd.match.i2c.adapter_id = async_sd->i2c_adapter_id;
-		ceu_sd->asd.match.i2c.address = async_sd->i2c_address;
-
-		ret = v4l2_async_notifier_add_subdev(&ceudev->notifier,
-						     &ceu_sd->asd);
-		if (ret) {
+		asd = v4l2_async_notifier_add_i2c_subdev(&ceudev->notifier,
+				async_sd->i2c_adapter_id,
+				async_sd->i2c_address,
+				sizeof(*ceu_sd));
+		if (IS_ERR(asd)) {
 			v4l2_async_notifier_cleanup(&ceudev->notifier);
-			return ret;
+			return PTR_ERR(asd);
 		}
+		ceu_sd = to_ceu_subdev(asd);
+		ceu_sd->mbus_flags = async_sd->flags;
+		ceudev->subdevs[i] = ceu_sd;
 	}
 
 	return pdata->num_subdevs;
@@ -1536,7 +1533,8 @@ static int ceu_parse_platform_data(struct ceu_device *ceudev,
 static int ceu_parse_dt(struct ceu_device *ceudev)
 {
 	struct device_node *of = ceudev->dev->of_node;
-	struct device_node *ep, *remote;
+	struct device_node *ep;
+	struct v4l2_async_subdev *asd;
 	struct ceu_subdev *ceu_sd;
 	unsigned int i;
 	int num_ep;
@@ -1578,20 +1576,16 @@ static int ceu_parse_dt(struct ceu_device *ceudev)
 		}
 
 		/* Setup the ceu subdevice and the async subdevice. */
-		ceu_sd = &ceudev->subdevs[i];
-		INIT_LIST_HEAD(&ceu_sd->asd.list);
-
-		remote = of_graph_get_remote_port_parent(ep);
-		ceu_sd->mbus_flags = fw_ep.bus.parallel.flags;
-		ceu_sd->asd.match_type = V4L2_ASYNC_MATCH_FWNODE;
-		ceu_sd->asd.match.fwnode = of_fwnode_handle(remote);
-
-		ret = v4l2_async_notifier_add_subdev(&ceudev->notifier,
-						     &ceu_sd->asd);
-		if (ret) {
-			of_node_put(remote);
+		asd = v4l2_async_notifier_add_fwnode_remote_subdev(
+				&ceudev->notifier, of_fwnode_handle(ep),
+				sizeof(*ceu_sd));
+		if (IS_ERR(asd)) {
+			ret = PTR_ERR(asd);
 			goto error_cleanup;
 		}
+		ceu_sd = to_ceu_subdev(asd);
+		ceu_sd->mbus_flags = fw_ep.bus.parallel.flags;
+		ceudev->subdevs[i] = ceu_sd;
 
 		of_node_put(ep);
 	}
-- 
2.29.2


^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCH v5 09/13] media: pxa-camera: Use v4l2_async_notifier_add_*_subdev
  2021-02-02 13:55 [PATCH v5 00/13] V4L2 Async notifier API cleanup Sakari Ailus
                   ` (7 preceding siblings ...)
  2021-02-02 13:56 ` [PATCH v5 08/13] media: renesas-ceu: " Sakari Ailus
@ 2021-02-02 13:56 ` Sakari Ailus
  2021-02-02 13:56 ` [PATCH v5 10/13] media: davinci: vpif_display: Remove unused v4l2-async code Sakari Ailus
                   ` (3 subsequent siblings)
  12 siblings, 0 replies; 25+ messages in thread
From: Sakari Ailus @ 2021-02-02 13:56 UTC (permalink / raw)
  To: linux-media
  Cc: Hans Verkuil, kernel, Laurent Pinchart, Kieran Bingham,
	Jacopo Mondi, niklas.soderlund+renesas, Helen Koike,
	Dafna Hirschfeld, Hugues Fruchet, Nicolas Ferre, Yong Zhi,
	Sylwester Nawrocki, Maxime Ripard, Robert Foss, Philipp Zabel,
	Ezequiel Garcia

From: Ezequiel Garcia <ezequiel@collabora.com>

The use of v4l2_async_notifier_add_subdev will be discouraged.
Drivers are instead encouraged to use a helper such as
v4l2_async_notifier_add_fwnode_remote_subdev.

This fixes a misuse of the API, as v4l2_async_notifier_add_subdev
should get a kmalloc'ed struct v4l2_async_subdev.

Use the appropriate helper: v4l2_async_notifier_add_i2c_subdev
or v4l2_async_notifier_add_fwnode_remote_subdev, which handles
the needed setup, instead of open-coding it.

Signed-off-by: Ezequiel Garcia <ezequiel@collabora.com>
Reviewed-by: Helen Koike <helen.koike@collabora.com>
Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
---
 drivers/media/platform/pxa_camera.c | 57 ++++++++++++-----------------
 1 file changed, 23 insertions(+), 34 deletions(-)

diff --git a/drivers/media/platform/pxa_camera.c b/drivers/media/platform/pxa_camera.c
index 75fad9689c90..b579ce2e93b6 100644
--- a/drivers/media/platform/pxa_camera.c
+++ b/drivers/media/platform/pxa_camera.c
@@ -656,8 +656,6 @@ struct pxa_camera_dev {
 	const struct pxa_camera_format_xlate *current_fmt;
 	struct v4l2_pix_format	current_pix;
 
-	struct v4l2_async_subdev asd;
-
 	/*
 	 * PXA27x is only supposed to handle one camera on its Quick Capture
 	 * interface. If anyone ever builds hardware to enable more than
@@ -2202,11 +2200,11 @@ static int pxa_camera_resume(struct device *dev)
 }
 
 static int pxa_camera_pdata_from_dt(struct device *dev,
-				    struct pxa_camera_dev *pcdev,
-				    struct v4l2_async_subdev *asd)
+				    struct pxa_camera_dev *pcdev)
 {
 	u32 mclk_rate;
-	struct device_node *remote, *np = dev->of_node;
+	struct v4l2_async_subdev *asd;
+	struct device_node *np = dev->of_node;
 	struct v4l2_fwnode_endpoint ep = { .bus_type = 0 };
 	int err = of_property_read_u32(np, "clock-frequency",
 				       &mclk_rate);
@@ -2258,13 +2256,12 @@ static int pxa_camera_pdata_from_dt(struct device *dev,
 	if (ep.bus.parallel.flags & V4L2_MBUS_PCLK_SAMPLE_FALLING)
 		pcdev->platform_flags |= PXA_CAMERA_PCLK_EN;
 
-	asd->match_type = V4L2_ASYNC_MATCH_FWNODE;
-	remote = of_graph_get_remote_port_parent(np);
-	if (remote)
-		asd->match.fwnode = of_fwnode_handle(remote);
-	else
-		dev_notice(dev, "no remote for %pOF\n", np);
-
+	asd = v4l2_async_notifier_add_fwnode_remote_subdev(
+				&pcdev->notifier,
+				of_fwnode_handle(np),
+				sizeof(*asd));
+	if (IS_ERR(asd))
+		err = PTR_ERR(asd);
 out:
 	of_node_put(np);
 
@@ -2300,18 +2297,23 @@ static int pxa_camera_probe(struct platform_device *pdev)
 	if (IS_ERR(pcdev->clk))
 		return PTR_ERR(pcdev->clk);
 
+	v4l2_async_notifier_init(&pcdev->notifier);
 	pcdev->res = res;
-
 	pcdev->pdata = pdev->dev.platform_data;
 	if (pcdev->pdata) {
+		struct v4l2_async_subdev *asd;
+
 		pcdev->platform_flags = pcdev->pdata->flags;
 		pcdev->mclk = pcdev->pdata->mclk_10khz * 10000;
-		pcdev->asd.match_type = V4L2_ASYNC_MATCH_I2C;
-		pcdev->asd.match.i2c.adapter_id =
-			pcdev->pdata->sensor_i2c_adapter_id;
-		pcdev->asd.match.i2c.address = pcdev->pdata->sensor_i2c_address;
+		asd = v4l2_async_notifier_add_i2c_subdev(
+				&pcdev->notifier,
+				pcdev->pdata->sensor_i2c_adapter_id,
+				pcdev->pdata->sensor_i2c_address,
+				sizeof(*asd));
+		if (IS_ERR(asd))
+			err = PTR_ERR(asd);
 	} else if (pdev->dev.of_node) {
-		err = pxa_camera_pdata_from_dt(&pdev->dev, pcdev, &pcdev->asd);
+		err = pxa_camera_pdata_from_dt(&pdev->dev, pcdev);
 	} else {
 		return -ENODEV;
 	}
@@ -2403,27 +2405,15 @@ static int pxa_camera_probe(struct platform_device *pdev)
 	if (err)
 		goto exit_deactivate;
 
-	v4l2_async_notifier_init(&pcdev->notifier);
-
-	err = v4l2_async_notifier_add_subdev(&pcdev->notifier, &pcdev->asd);
-	if (err) {
-		fwnode_handle_put(pcdev->asd.match.fwnode);
-		goto exit_free_v4l2dev;
-	}
-
-	pcdev->notifier.ops = &pxa_camera_sensor_ops;
-
-	if (!of_have_populated_dt())
-		pcdev->asd.match_type = V4L2_ASYNC_MATCH_I2C;
-
 	err = pxa_camera_init_videobuf2(pcdev);
 	if (err)
 		goto exit_notifier_cleanup;
 
 	v4l2_clk_name_i2c(clk_name, sizeof(clk_name),
-			  pcdev->asd.match.i2c.adapter_id,
-			  pcdev->asd.match.i2c.address);
+			  pcdev->pdata->sensor_i2c_adapter_id,
+			  pcdev->pdata->sensor_i2c_address);
 
+	pcdev->notifier.ops = &pxa_camera_sensor_ops;
 	pcdev->mclk_clk = v4l2_clk_register(&pxa_camera_mclk_ops, clk_name, NULL);
 	if (IS_ERR(pcdev->mclk_clk)) {
 		err = PTR_ERR(pcdev->mclk_clk);
@@ -2439,7 +2429,6 @@ static int pxa_camera_probe(struct platform_device *pdev)
 	v4l2_clk_unregister(pcdev->mclk_clk);
 exit_notifier_cleanup:
 	v4l2_async_notifier_cleanup(&pcdev->notifier);
-exit_free_v4l2dev:
 	v4l2_device_unregister(&pcdev->v4l2_dev);
 exit_deactivate:
 	pxa_camera_deactivate(pcdev);
-- 
2.29.2


^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCH v5 10/13] media: davinci: vpif_display: Remove unused v4l2-async code
  2021-02-02 13:55 [PATCH v5 00/13] V4L2 Async notifier API cleanup Sakari Ailus
                   ` (8 preceding siblings ...)
  2021-02-02 13:56 ` [PATCH v5 09/13] media: pxa-camera: " Sakari Ailus
@ 2021-02-02 13:56 ` Sakari Ailus
  2021-02-02 13:56 ` [PATCH v5 11/13] media: v4l2-async: Discourage use of v4l2_async_notifier_add_subdev Sakari Ailus
                   ` (2 subsequent siblings)
  12 siblings, 0 replies; 25+ messages in thread
From: Sakari Ailus @ 2021-02-02 13:56 UTC (permalink / raw)
  To: linux-media
  Cc: Hans Verkuil, kernel, Laurent Pinchart, Kieran Bingham,
	Jacopo Mondi, niklas.soderlund+renesas, Helen Koike,
	Dafna Hirschfeld, Hugues Fruchet, Nicolas Ferre, Yong Zhi,
	Sylwester Nawrocki, Maxime Ripard, Robert Foss, Philipp Zabel,
	Ezequiel Garcia

From: Ezequiel Garcia <ezequiel@collabora.com>

There are no users for vpif_display_config.asd_sizes
and vpif_display_config.asd members, which means the v4l2-async
subdevices aren't being defined anywhere.

Remove the v4l2-async, leaving only the synchronous setup.

Signed-off-by: Ezequiel Garcia <ezequiel@collabora.com>
Reviewed-by: Helen Koike <helen.koike@collabora.com>
Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
---
 drivers/media/platform/davinci/vpif_display.c | 86 ++++---------------
 drivers/media/platform/davinci/vpif_display.h |  1 -
 include/media/davinci/vpif_types.h            |  2 -
 3 files changed, 15 insertions(+), 74 deletions(-)

diff --git a/drivers/media/platform/davinci/vpif_display.c b/drivers/media/platform/davinci/vpif_display.c
index 46afc029138f..e5f61d9b221d 100644
--- a/drivers/media/platform/davinci/vpif_display.c
+++ b/drivers/media/platform/davinci/vpif_display.c
@@ -1117,23 +1117,6 @@ static void free_vpif_objs(void)
 		kfree(vpif_obj.dev[i]);
 }
 
-static int vpif_async_bound(struct v4l2_async_notifier *notifier,
-			    struct v4l2_subdev *subdev,
-			    struct v4l2_async_subdev *asd)
-{
-	int i;
-
-	for (i = 0; i < vpif_obj.config->subdev_count; i++)
-		if (!strcmp(vpif_obj.config->subdevinfo[i].name,
-			    subdev->name)) {
-			vpif_obj.sd[i] = subdev;
-			vpif_obj.sd[i]->grp_id = 1 << i;
-			return 0;
-		}
-
-	return -EINVAL;
-}
-
 static int vpif_probe_complete(void)
 {
 	struct common_obj *common;
@@ -1230,16 +1213,6 @@ static int vpif_probe_complete(void)
 	return err;
 }
 
-static int vpif_async_complete(struct v4l2_async_notifier *notifier)
-{
-	return vpif_probe_complete();
-}
-
-static const struct v4l2_async_notifier_operations vpif_async_ops = {
-	.bound = vpif_async_bound,
-	.complete = vpif_async_complete,
-};
-
 /*
  * vpif_probe: This function creates device entries by register itself to the
  * V4L2 driver and initializes fields of each channel objects
@@ -1294,52 +1267,28 @@ static __init int vpif_probe(struct platform_device *pdev)
 		goto vpif_unregister;
 	}
 
-	v4l2_async_notifier_init(&vpif_obj.notifier);
-
-	if (!vpif_obj.config->asd_sizes) {
-		i2c_adap = i2c_get_adapter(vpif_obj.config->i2c_adapter_id);
-		for (i = 0; i < subdev_count; i++) {
-			vpif_obj.sd[i] =
-				v4l2_i2c_new_subdev_board(&vpif_obj.v4l2_dev,
-							  i2c_adap,
-							  &subdevdata[i].
-							  board_info,
-							  NULL);
-			if (!vpif_obj.sd[i]) {
-				vpif_err("Error registering v4l2 subdevice\n");
-				err = -ENODEV;
-				goto probe_subdev_out;
-			}
-
-			if (vpif_obj.sd[i])
-				vpif_obj.sd[i]->grp_id = 1 << i;
-		}
-		err = vpif_probe_complete();
-		if (err) {
+	i2c_adap = i2c_get_adapter(vpif_obj.config->i2c_adapter_id);
+	for (i = 0; i < subdev_count; i++) {
+		vpif_obj.sd[i] =
+			v4l2_i2c_new_subdev_board(&vpif_obj.v4l2_dev,
+						  i2c_adap,
+						  &subdevdata[i].board_info,
+						  NULL);
+		if (!vpif_obj.sd[i]) {
+			vpif_err("Error registering v4l2 subdevice\n");
+			err = -ENODEV;
 			goto probe_subdev_out;
 		}
-	} else {
-		for (i = 0; i < vpif_obj.config->asd_sizes[0]; i++) {
-			err = v4l2_async_notifier_add_subdev(
-				&vpif_obj.notifier, vpif_obj.config->asd[i]);
-			if (err)
-				goto probe_cleanup;
-		}
 
-		vpif_obj.notifier.ops = &vpif_async_ops;
-		err = v4l2_async_notifier_register(&vpif_obj.v4l2_dev,
-						   &vpif_obj.notifier);
-		if (err) {
-			vpif_err("Error registering async notifier\n");
-			err = -EINVAL;
-			goto probe_cleanup;
-		}
+		if (vpif_obj.sd[i])
+			vpif_obj.sd[i]->grp_id = 1 << i;
 	}
+	err = vpif_probe_complete();
+	if (err)
+		goto probe_subdev_out;
 
 	return 0;
 
-probe_cleanup:
-	v4l2_async_notifier_cleanup(&vpif_obj.notifier);
 probe_subdev_out:
 	kfree(vpif_obj.sd);
 vpif_unregister:
@@ -1358,11 +1307,6 @@ static int vpif_remove(struct platform_device *device)
 	struct channel_obj *ch;
 	int i;
 
-	if (vpif_obj.config->asd_sizes) {
-		v4l2_async_notifier_unregister(&vpif_obj.notifier);
-		v4l2_async_notifier_cleanup(&vpif_obj.notifier);
-	}
-
 	v4l2_device_unregister(&vpif_obj.v4l2_dev);
 
 	kfree(vpif_obj.sd);
diff --git a/drivers/media/platform/davinci/vpif_display.h b/drivers/media/platform/davinci/vpif_display.h
index f731a65eefd6..f98062e79167 100644
--- a/drivers/media/platform/davinci/vpif_display.h
+++ b/drivers/media/platform/davinci/vpif_display.h
@@ -118,7 +118,6 @@ struct vpif_device {
 	struct v4l2_device v4l2_dev;
 	struct channel_obj *dev[VPIF_DISPLAY_NUM_CHANNELS];
 	struct v4l2_subdev **sd;
-	struct v4l2_async_notifier notifier;
 	struct vpif_display_config *config;
 };
 
diff --git a/include/media/davinci/vpif_types.h b/include/media/davinci/vpif_types.h
index 8439e46fb993..d03e5c54347a 100644
--- a/include/media/davinci/vpif_types.h
+++ b/include/media/davinci/vpif_types.h
@@ -48,8 +48,6 @@ struct vpif_display_config {
 	int i2c_adapter_id;
 	struct vpif_display_chan_config chan_config[VPIF_DISPLAY_MAX_CHANNELS];
 	const char *card_name;
-	struct v4l2_async_subdev **asd;	/* Flat array, arranged in groups */
-	int *asd_sizes;		/* 0-terminated array of asd group sizes */
 };
 
 struct vpif_input {
-- 
2.29.2


^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCH v5 11/13] media: v4l2-async: Discourage use of v4l2_async_notifier_add_subdev
  2021-02-02 13:55 [PATCH v5 00/13] V4L2 Async notifier API cleanup Sakari Ailus
                   ` (9 preceding siblings ...)
  2021-02-02 13:56 ` [PATCH v5 10/13] media: davinci: vpif_display: Remove unused v4l2-async code Sakari Ailus
@ 2021-02-02 13:56 ` Sakari Ailus
  2021-02-06  8:15   ` Mauro Carvalho Chehab
  2021-02-02 13:56 ` [PATCH v5 12/13] media: v4l2-async: Improve v4l2_async_notifier_add_*_subdev() API Sakari Ailus
  2021-02-02 13:56 ` [PATCH v5 13/13] media: Clarify v4l2-async subdevice addition API Sakari Ailus
  12 siblings, 1 reply; 25+ messages in thread
From: Sakari Ailus @ 2021-02-02 13:56 UTC (permalink / raw)
  To: linux-media
  Cc: Hans Verkuil, kernel, Laurent Pinchart, Kieran Bingham,
	Jacopo Mondi, niklas.soderlund+renesas, Helen Koike,
	Dafna Hirschfeld, Hugues Fruchet, Nicolas Ferre, Yong Zhi,
	Sylwester Nawrocki, Maxime Ripard, Robert Foss, Philipp Zabel,
	Ezequiel Garcia

From: Ezequiel Garcia <ezequiel@collabora.com>

Most -if not all- use-cases are expected to be covered by one of:
v4l2_async_notifier_add_fwnode_subdev,
v4l2_async_notifier_add_fwnode_remote_subdev or
v4l2_async_notifier_add_i2c_subdev.

We'd like to discourage drivers from using v4l2_async_notifier_add_subdev,
so rename it as __v4l2_async_notifier_add_subdev. This is
typically a good hint for drivers to avoid using the function.

Signed-off-by: Ezequiel Garcia <ezequiel@collabora.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Helen Koike <helen.koike@collabora.com>
Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
---
 drivers/media/v4l2-core/v4l2-async.c  | 8 ++++----
 drivers/media/v4l2-core/v4l2-fwnode.c | 2 +-
 include/media/v4l2-async.h            | 9 +++++++--
 3 files changed, 12 insertions(+), 7 deletions(-)

diff --git a/drivers/media/v4l2-core/v4l2-async.c b/drivers/media/v4l2-core/v4l2-async.c
index ed603ae63cad..d848db962dc7 100644
--- a/drivers/media/v4l2-core/v4l2-async.c
+++ b/drivers/media/v4l2-core/v4l2-async.c
@@ -611,7 +611,7 @@ void v4l2_async_notifier_cleanup(struct v4l2_async_notifier *notifier)
 }
 EXPORT_SYMBOL_GPL(v4l2_async_notifier_cleanup);
 
-int v4l2_async_notifier_add_subdev(struct v4l2_async_notifier *notifier,
+int __v4l2_async_notifier_add_subdev(struct v4l2_async_notifier *notifier,
 				   struct v4l2_async_subdev *asd)
 {
 	int ret;
@@ -628,7 +628,7 @@ int v4l2_async_notifier_add_subdev(struct v4l2_async_notifier *notifier,
 	mutex_unlock(&list_lock);
 	return ret;
 }
-EXPORT_SYMBOL_GPL(v4l2_async_notifier_add_subdev);
+EXPORT_SYMBOL_GPL(__v4l2_async_notifier_add_subdev);
 
 struct v4l2_async_subdev *
 v4l2_async_notifier_add_fwnode_subdev(struct v4l2_async_notifier *notifier,
@@ -645,7 +645,7 @@ v4l2_async_notifier_add_fwnode_subdev(struct v4l2_async_notifier *notifier,
 	asd->match_type = V4L2_ASYNC_MATCH_FWNODE;
 	asd->match.fwnode = fwnode_handle_get(fwnode);
 
-	ret = v4l2_async_notifier_add_subdev(notifier, asd);
+	ret = __v4l2_async_notifier_add_subdev(notifier, asd);
 	if (ret) {
 		fwnode_handle_put(fwnode);
 		kfree(asd);
@@ -695,7 +695,7 @@ v4l2_async_notifier_add_i2c_subdev(struct v4l2_async_notifier *notifier,
 	asd->match.i2c.adapter_id = adapter_id;
 	asd->match.i2c.address = address;
 
-	ret = v4l2_async_notifier_add_subdev(notifier, asd);
+	ret = __v4l2_async_notifier_add_subdev(notifier, asd);
 	if (ret) {
 		kfree(asd);
 		return ERR_PTR(ret);
diff --git a/drivers/media/v4l2-core/v4l2-fwnode.c b/drivers/media/v4l2-core/v4l2-fwnode.c
index c1c2b3060532..63be16c8eb83 100644
--- a/drivers/media/v4l2-core/v4l2-fwnode.c
+++ b/drivers/media/v4l2-core/v4l2-fwnode.c
@@ -822,7 +822,7 @@ v4l2_async_notifier_fwnode_parse_endpoint(struct device *dev,
 	if (ret < 0)
 		goto out_err;
 
-	ret = v4l2_async_notifier_add_subdev(notifier, asd);
+	ret = __v4l2_async_notifier_add_subdev(notifier, asd);
 	if (ret < 0) {
 		/* not an error if asd already exists */
 		if (ret == -EEXIST)
diff --git a/include/media/v4l2-async.h b/include/media/v4l2-async.h
index 8815e233677e..b113329582ff 100644
--- a/include/media/v4l2-async.h
+++ b/include/media/v4l2-async.h
@@ -133,17 +133,22 @@ void v4l2_async_debug_init(struct dentry *debugfs_dir);
 void v4l2_async_notifier_init(struct v4l2_async_notifier *notifier);
 
 /**
- * v4l2_async_notifier_add_subdev - Add an async subdev to the
+ * __v4l2_async_notifier_add_subdev - Add an async subdev to the
  *				notifier's master asd list.
  *
  * @notifier: pointer to &struct v4l2_async_notifier
  * @asd: pointer to &struct v4l2_async_subdev
  *
+ * \warning: Drivers should avoid using this function and instead use one of:
+ * @v4l2_async_notifier_add_fwnode_subdev,
+ * @v4l2_async_notifier_add_fwnode_remote_subdev or
+ * @v4l2_async_notifier_add_i2c_subdev.
+ *
  * Call this function before registering a notifier to link the provided @asd to
  * the notifiers master @asd_list. The @asd must be allocated with k*alloc() as
  * it will be freed by the framework when the notifier is destroyed.
  */
-int v4l2_async_notifier_add_subdev(struct v4l2_async_notifier *notifier,
+int __v4l2_async_notifier_add_subdev(struct v4l2_async_notifier *notifier,
 				   struct v4l2_async_subdev *asd);
 
 /**
-- 
2.29.2


^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCH v5 12/13] media: v4l2-async: Improve v4l2_async_notifier_add_*_subdev() API
  2021-02-02 13:55 [PATCH v5 00/13] V4L2 Async notifier API cleanup Sakari Ailus
                   ` (10 preceding siblings ...)
  2021-02-02 13:56 ` [PATCH v5 11/13] media: v4l2-async: Discourage use of v4l2_async_notifier_add_subdev Sakari Ailus
@ 2021-02-02 13:56 ` Sakari Ailus
  2021-02-02 13:56 ` [PATCH v5 13/13] media: Clarify v4l2-async subdevice addition API Sakari Ailus
  12 siblings, 0 replies; 25+ messages in thread
From: Sakari Ailus @ 2021-02-02 13:56 UTC (permalink / raw)
  To: linux-media
  Cc: Hans Verkuil, kernel, Laurent Pinchart, Kieran Bingham,
	Jacopo Mondi, niklas.soderlund+renesas, Helen Koike,
	Dafna Hirschfeld, Hugues Fruchet, Nicolas Ferre, Yong Zhi,
	Sylwester Nawrocki, Maxime Ripard, Robert Foss, Philipp Zabel,
	Ezequiel Garcia

From: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>

The functions that add an async subdev to an async subdev notifier take
as an argument the size of the container structure they need to
allocate. This is error prone, as passing an invalid size will not be
caught by the compiler. Wrap those functions in macros that take a
container type instead of a size, and cast the returned pointer to the
desired type. The compiler will catch mistakes if the incorrect type is
passed to the macro, as the assignment types won't match.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
Reviewed-by: Niklas Söderlund <niklas.soderlund+renesas@ragnatech.se>
Reviewed-by: Jacopo Mondi <jacopo+renesas@jmondi.org>
Signed-off-by: Ezequiel Garcia <ezequiel@collabora.com>
Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
Reviewed-by: Helen Koike <helen.koike@collabora.com>
---
 drivers/media/i2c/max9286.c                   | 14 ++++-----
 drivers/media/i2c/st-mipid02.c                |  2 +-
 drivers/media/pci/intel/ipu3/ipu3-cio2-main.c | 10 +++----
 drivers/media/platform/am437x/am437x-vpfe.c   |  2 +-
 drivers/media/platform/atmel/atmel-isi.c      |  2 +-
 .../media/platform/atmel/atmel-sama5d2-isc.c  |  2 +-
 drivers/media/platform/cadence/cdns-csi2rx.c  |  3 +-
 drivers/media/platform/davinci/vpif_capture.c |  2 +-
 drivers/media/platform/exynos4-is/media-dev.c |  3 +-
 .../media/platform/marvell-ccic/cafe-driver.c |  2 +-
 .../media/platform/marvell-ccic/mmp-driver.c  |  4 +--
 drivers/media/platform/omap3isp/isp.c         | 17 ++++-------
 drivers/media/platform/pxa_camera.c           |  4 +--
 drivers/media/platform/qcom/camss/camss.c     | 11 +++----
 drivers/media/platform/rcar-vin/rcar-core.c   |  5 ++--
 drivers/media/platform/rcar-vin/rcar-csi2.c   |  2 +-
 drivers/media/platform/rcar_drif.c            |  2 +-
 drivers/media/platform/renesas-ceu.c          | 20 +++++--------
 .../platform/rockchip/rkisp1/rkisp1-dev.c     | 12 ++++----
 drivers/media/platform/stm32/stm32-dcmi.c     |  3 +-
 .../platform/sunxi/sun4i-csi/sun4i_csi.c      |  4 +--
 drivers/media/platform/ti-vpe/cal.c           | 12 ++++----
 drivers/media/platform/video-mux.c            |  2 +-
 drivers/media/platform/xilinx/xilinx-vipp.c   | 10 +++----
 drivers/media/v4l2-core/v4l2-async.c          | 30 +++++++++----------
 drivers/media/v4l2-core/v4l2-fwnode.c         |  4 +--
 drivers/staging/media/imx/imx-media-csi.c     |  2 +-
 drivers/staging/media/imx/imx-media-of.c      |  2 +-
 drivers/staging/media/imx/imx6-mipi-csi2.c    |  2 +-
 drivers/staging/media/imx/imx7-media-csi.c    |  2 +-
 drivers/staging/media/imx/imx7-mipi-csis.c    |  2 +-
 drivers/staging/media/tegra-video/vi.c        | 10 +++----
 include/media/v4l2-async.h                    | 27 +++++++++++------
 33 files changed, 113 insertions(+), 118 deletions(-)

diff --git a/drivers/media/i2c/max9286.c b/drivers/media/i2c/max9286.c
index b1e2476d3c9e..fd2151f2fa36 100644
--- a/drivers/media/i2c/max9286.c
+++ b/drivers/media/i2c/max9286.c
@@ -576,19 +576,19 @@ static int max9286_v4l2_notifier_register(struct max9286_priv *priv)
 
 	for_each_source(priv, source) {
 		unsigned int i = to_index(priv, source);
-		struct v4l2_async_subdev *asd;
+		struct max9286_asd *mas;
 
-		asd = v4l2_async_notifier_add_fwnode_subdev(&priv->notifier,
+		mas = v4l2_async_notifier_add_fwnode_subdev(&priv->notifier,
 							    source->fwnode,
-							    sizeof(struct max9286_asd));
-		if (IS_ERR(asd)) {
+							    struct max9286_asd);
+		if (IS_ERR(mas)) {
 			dev_err(dev, "Failed to add subdev for source %u: %ld",
-				i, PTR_ERR(asd));
+				i, PTR_ERR(mas));
 			v4l2_async_notifier_cleanup(&priv->notifier);
-			return PTR_ERR(asd);
+			return PTR_ERR(mas);
 		}
 
-		to_max9286_asd(asd)->source = source;
+		mas->source = source;
 	}
 
 	priv->notifier.ops = &max9286_notify_ops;
diff --git a/drivers/media/i2c/st-mipid02.c b/drivers/media/i2c/st-mipid02.c
index bb32a5278a4e..7f07ef56fbbd 100644
--- a/drivers/media/i2c/st-mipid02.c
+++ b/drivers/media/i2c/st-mipid02.c
@@ -879,7 +879,7 @@ static int mipid02_parse_rx_ep(struct mipid02_dev *bridge)
 	asd = v4l2_async_notifier_add_fwnode_remote_subdev(
 					&bridge->notifier,
 					of_fwnode_handle(ep_node),
-					sizeof(*asd));
+					struct v4l2_async_subdev);
 	of_node_put(ep_node);
 
 	if (IS_ERR(asd)) {
diff --git a/drivers/media/pci/intel/ipu3/ipu3-cio2-main.c b/drivers/media/pci/intel/ipu3/ipu3-cio2-main.c
index 8fd311fee4e7..1b2bea86cfd1 100644
--- a/drivers/media/pci/intel/ipu3/ipu3-cio2-main.c
+++ b/drivers/media/pci/intel/ipu3/ipu3-cio2-main.c
@@ -1465,7 +1465,6 @@ static int cio2_parse_firmware(struct cio2_device *cio2)
 			.bus_type = V4L2_MBUS_CSI2_DPHY
 		};
 		struct sensor_async_subdev *s_asd;
-		struct v4l2_async_subdev *asd;
 		struct fwnode_handle *ep;
 
 		ep = fwnode_graph_get_endpoint_by_id(
@@ -1479,14 +1478,13 @@ static int cio2_parse_firmware(struct cio2_device *cio2)
 		if (ret)
 			goto err_parse;
 
-		asd = v4l2_async_notifier_add_fwnode_remote_subdev(
-				&cio2->notifier, ep, sizeof(*s_asd));
-		if (IS_ERR(asd)) {
-			ret = PTR_ERR(asd);
+		s_asd = v4l2_async_notifier_add_fwnode_remote_subdev(
+				&cio2->notifier, ep, struct sensor_async_subdev);
+		if (IS_ERR(s_asd)) {
+			ret = PTR_ERR(s_asd);
 			goto err_parse;
 		}
 
-		s_asd = container_of(asd, struct sensor_async_subdev, asd);
 		s_asd->csi2.port = vep.base.port;
 		s_asd->csi2.lanes = vep.bus.mipi_csi2.num_data_lanes;
 
diff --git a/drivers/media/platform/am437x/am437x-vpfe.c b/drivers/media/platform/am437x/am437x-vpfe.c
index 0fb9f9ba1219..6cdc77dda0e4 100644
--- a/drivers/media/platform/am437x/am437x-vpfe.c
+++ b/drivers/media/platform/am437x/am437x-vpfe.c
@@ -2365,7 +2365,7 @@ vpfe_get_pdata(struct vpfe_device *vpfe)
 
 		pdata->asd[i] = v4l2_async_notifier_add_fwnode_subdev(
 			&vpfe->notifier, of_fwnode_handle(rem),
-			sizeof(struct v4l2_async_subdev));
+			struct v4l2_async_subdev);
 		of_node_put(rem);
 		if (IS_ERR(pdata->asd[i]))
 			goto cleanup;
diff --git a/drivers/media/platform/atmel/atmel-isi.c b/drivers/media/platform/atmel/atmel-isi.c
index c1a6dd7af002..0514be6153df 100644
--- a/drivers/media/platform/atmel/atmel-isi.c
+++ b/drivers/media/platform/atmel/atmel-isi.c
@@ -1150,7 +1150,7 @@ static int isi_graph_init(struct atmel_isi *isi)
 	asd = v4l2_async_notifier_add_fwnode_remote_subdev(
 						&isi->notifier,
 						of_fwnode_handle(ep),
-						sizeof(*asd));
+						struct v4l2_async_subdev);
 	of_node_put(ep);
 
 	if (IS_ERR(asd))
diff --git a/drivers/media/platform/atmel/atmel-sama5d2-isc.c b/drivers/media/platform/atmel/atmel-sama5d2-isc.c
index 9ee2cd194f93..0b78fecfd2a8 100644
--- a/drivers/media/platform/atmel/atmel-sama5d2-isc.c
+++ b/drivers/media/platform/atmel/atmel-sama5d2-isc.c
@@ -214,7 +214,7 @@ static int atmel_isc_probe(struct platform_device *pdev)
 		asd = v4l2_async_notifier_add_fwnode_remote_subdev(
 					&subdev_entity->notifier,
 					of_fwnode_handle(subdev_entity->epn),
-					sizeof(*asd));
+					struct v4l2_async_subdev);
 
 		of_node_put(subdev_entity->epn);
 		subdev_entity->epn = NULL;
diff --git a/drivers/media/platform/cadence/cdns-csi2rx.c b/drivers/media/platform/cadence/cdns-csi2rx.c
index 7d299cacef8c..c68a3eac62cd 100644
--- a/drivers/media/platform/cadence/cdns-csi2rx.c
+++ b/drivers/media/platform/cadence/cdns-csi2rx.c
@@ -398,7 +398,8 @@ static int csi2rx_parse_dt(struct csi2rx_priv *csi2rx)
 	v4l2_async_notifier_init(&csi2rx->notifier);
 
 	asd = v4l2_async_notifier_add_fwnode_remote_subdev(&csi2rx->notifier,
-							   fwh, sizeof(*asd));
+							   fwh,
+							   struct v4l2_async_subdev);
 	of_node_put(ep);
 	if (IS_ERR(asd))
 		return PTR_ERR(asd);
diff --git a/drivers/media/platform/davinci/vpif_capture.c b/drivers/media/platform/davinci/vpif_capture.c
index 72a0e94e2e21..8d2e165bf7de 100644
--- a/drivers/media/platform/davinci/vpif_capture.c
+++ b/drivers/media/platform/davinci/vpif_capture.c
@@ -1584,7 +1584,7 @@ vpif_capture_get_pdata(struct platform_device *pdev)
 
 		pdata->asd[i] = v4l2_async_notifier_add_fwnode_subdev(
 			&vpif_obj.notifier, of_fwnode_handle(rem),
-			sizeof(struct v4l2_async_subdev));
+			struct v4l2_async_subdev);
 		if (IS_ERR(pdata->asd[i]))
 			goto err_cleanup;
 
diff --git a/drivers/media/platform/exynos4-is/media-dev.c b/drivers/media/platform/exynos4-is/media-dev.c
index f4687b0cbd65..8e1e892085ec 100644
--- a/drivers/media/platform/exynos4-is/media-dev.c
+++ b/drivers/media/platform/exynos4-is/media-dev.c
@@ -465,7 +465,8 @@ static int fimc_md_parse_one_endpoint(struct fimc_md *fmd,
 	}
 
 	asd = v4l2_async_notifier_add_fwnode_remote_subdev(
-		&fmd->subdev_notifier, of_fwnode_handle(ep), sizeof(*asd));
+		&fmd->subdev_notifier, of_fwnode_handle(ep),
+		struct v4l2_async_subdev);
 
 	of_node_put(ep);
 
diff --git a/drivers/media/platform/marvell-ccic/cafe-driver.c b/drivers/media/platform/marvell-ccic/cafe-driver.c
index 91d65f71be96..9c94a8b58b7c 100644
--- a/drivers/media/platform/marvell-ccic/cafe-driver.c
+++ b/drivers/media/platform/marvell-ccic/cafe-driver.c
@@ -552,7 +552,7 @@ static int cafe_pci_probe(struct pci_dev *pdev,
 	asd = v4l2_async_notifier_add_i2c_subdev(&mcam->notifier,
 					i2c_adapter_id(cam->i2c_adapter),
 					ov7670_info.addr,
-					sizeof(*asd));
+					struct v4l2_async_subdev);
 	if (IS_ERR(asd)) {
 		ret = PTR_ERR(asd);
 		goto out_smbus_shutdown;
diff --git a/drivers/media/platform/marvell-ccic/mmp-driver.c b/drivers/media/platform/marvell-ccic/mmp-driver.c
index 40d9fc4a731a..f2f09cea751d 100644
--- a/drivers/media/platform/marvell-ccic/mmp-driver.c
+++ b/drivers/media/platform/marvell-ccic/mmp-driver.c
@@ -241,8 +241,8 @@ static int mmpcam_probe(struct platform_device *pdev)
 
 	v4l2_async_notifier_init(&mcam->notifier);
 
-	asd = v4l2_async_notifier_add_fwnode_remote_subdev(&mcam->notifier,
-							   ep, sizeof(*asd));
+	asd = v4l2_async_notifier_add_fwnode_remote_subdev(&mcam->notifier, ep,
+							   struct v4l2_async_subdev);
 	fwnode_handle_put(ep);
 	if (IS_ERR(asd)) {
 		ret = PTR_ERR(asd);
diff --git a/drivers/media/platform/omap3isp/isp.c b/drivers/media/platform/omap3isp/isp.c
index 1311b4996ece..a6bb7d9bf75f 100644
--- a/drivers/media/platform/omap3isp/isp.c
+++ b/drivers/media/platform/omap3isp/isp.c
@@ -2141,7 +2141,6 @@ static int isp_parse_of_endpoints(struct isp_device *isp)
 {
 	struct fwnode_handle *ep;
 	struct isp_async_subdev *isd = NULL;
-	struct v4l2_async_subdev *asd;
 	unsigned int i;
 
 	ep = fwnode_graph_get_endpoint_by_id(
@@ -2159,12 +2158,10 @@ static int isp_parse_of_endpoints(struct isp_device *isp)
 		ret = v4l2_fwnode_endpoint_parse(ep, &vep);
 
 		if (!ret) {
-			asd = v4l2_async_notifier_add_fwnode_remote_subdev(
-				&isp->notifier, ep, sizeof(*isd));
-			if (!IS_ERR(asd)) {
-				isd = container_of(asd, struct isp_async_subdev, asd);
+			isd = v4l2_async_notifier_add_fwnode_remote_subdev(
+				&isp->notifier, ep, struct isp_async_subdev);
+			if (!IS_ERR(isd))
 				isp_parse_of_parallel_endpoint(isp->dev, &vep, &isd->bus);
-			}
 		}
 
 		fwnode_handle_put(ep);
@@ -2200,12 +2197,10 @@ static int isp_parse_of_endpoints(struct isp_device *isp)
 		}
 
 		if (!ret) {
-			asd = v4l2_async_notifier_add_fwnode_remote_subdev(
-				&isp->notifier, ep, sizeof(*isd));
-
-			if (!IS_ERR(asd)) {
-				isd = container_of(asd, struct isp_async_subdev, asd);
+			isd = v4l2_async_notifier_add_fwnode_remote_subdev(
+				&isp->notifier, ep, struct isp_async_subdev);
 
+			if (!IS_ERR(isd)) {
 				switch (vep.bus_type) {
 				case V4L2_MBUS_CSI2_DPHY:
 					isd->bus.interface =
diff --git a/drivers/media/platform/pxa_camera.c b/drivers/media/platform/pxa_camera.c
index b579ce2e93b6..7f92de351c52 100644
--- a/drivers/media/platform/pxa_camera.c
+++ b/drivers/media/platform/pxa_camera.c
@@ -2259,7 +2259,7 @@ static int pxa_camera_pdata_from_dt(struct device *dev,
 	asd = v4l2_async_notifier_add_fwnode_remote_subdev(
 				&pcdev->notifier,
 				of_fwnode_handle(np),
-				sizeof(*asd));
+				struct v4l2_async_subdev);
 	if (IS_ERR(asd))
 		err = PTR_ERR(asd);
 out:
@@ -2309,7 +2309,7 @@ static int pxa_camera_probe(struct platform_device *pdev)
 				&pcdev->notifier,
 				pcdev->pdata->sensor_i2c_adapter_id,
 				pcdev->pdata->sensor_i2c_address,
-				sizeof(*asd));
+				struct v4l2_async_subdev);
 		if (IS_ERR(asd))
 			err = PTR_ERR(asd);
 	} else if (pdev->dev.of_node) {
diff --git a/drivers/media/platform/qcom/camss/camss.c b/drivers/media/platform/qcom/camss/camss.c
index 8fefce57bc49..7c0f669f8aa6 100644
--- a/drivers/media/platform/qcom/camss/camss.c
+++ b/drivers/media/platform/qcom/camss/camss.c
@@ -655,7 +655,6 @@ static int camss_of_parse_ports(struct camss *camss)
 
 	for_each_endpoint_of_node(dev->of_node, node) {
 		struct camss_async_subdev *csd;
-		struct v4l2_async_subdev *asd;
 
 		if (!of_device_is_available(node))
 			continue;
@@ -667,17 +666,15 @@ static int camss_of_parse_ports(struct camss *camss)
 			goto err_cleanup;
 		}
 
-		asd = v4l2_async_notifier_add_fwnode_subdev(
+		csd = v4l2_async_notifier_add_fwnode_subdev(
 			&camss->notifier, of_fwnode_handle(remote),
-			sizeof(*csd));
+			struct camss_async_subdev);
 		of_node_put(remote);
-		if (IS_ERR(asd)) {
-			ret = PTR_ERR(asd);
+		if (IS_ERR(csd)) {
+			ret = PTR_ERR(csd);
 			goto err_cleanup;
 		}
 
-		csd = container_of(asd, struct camss_async_subdev, asd);
-
 		ret = camss_of_parse_endpoint_node(dev, node, csd);
 		if (ret < 0)
 			goto err_cleanup;
diff --git a/drivers/media/platform/rcar-vin/rcar-core.c b/drivers/media/platform/rcar-vin/rcar-core.c
index 98bff765b02e..a9cc09653110 100644
--- a/drivers/media/platform/rcar-vin/rcar-core.c
+++ b/drivers/media/platform/rcar-vin/rcar-core.c
@@ -642,7 +642,7 @@ static int rvin_parallel_parse_of(struct rvin_dev *vin)
 	}
 
 	asd = v4l2_async_notifier_add_fwnode_subdev(&vin->notifier, fwnode,
-						    sizeof(*asd));
+						    struct v4l2_async_subdev);
 	if (IS_ERR(asd)) {
 		ret = PTR_ERR(asd);
 		goto out;
@@ -842,7 +842,8 @@ static int rvin_mc_parse_of(struct rvin_dev *vin, unsigned int id)
 	}
 
 	asd = v4l2_async_notifier_add_fwnode_subdev(&vin->group->notifier,
-						    fwnode, sizeof(*asd));
+						    fwnode,
+						    struct v4l2_async_subdev);
 	if (IS_ERR(asd)) {
 		ret = PTR_ERR(asd);
 		goto out;
diff --git a/drivers/media/platform/rcar-vin/rcar-csi2.c b/drivers/media/platform/rcar-vin/rcar-csi2.c
index 945d2eb87233..e06cd512aba2 100644
--- a/drivers/media/platform/rcar-vin/rcar-csi2.c
+++ b/drivers/media/platform/rcar-vin/rcar-csi2.c
@@ -910,7 +910,7 @@ static int rcsi2_parse_dt(struct rcar_csi2 *priv)
 	priv->notifier.ops = &rcar_csi2_notify_ops;
 
 	asd = v4l2_async_notifier_add_fwnode_subdev(&priv->notifier, fwnode,
-						    sizeof(*asd));
+						    struct v4l2_async_subdev);
 	fwnode_handle_put(fwnode);
 	if (IS_ERR(asd))
 		return PTR_ERR(asd);
diff --git a/drivers/media/platform/rcar_drif.c b/drivers/media/platform/rcar_drif.c
index f318cd4b8086..83bd9a412a56 100644
--- a/drivers/media/platform/rcar_drif.c
+++ b/drivers/media/platform/rcar_drif.c
@@ -1231,7 +1231,7 @@ static int rcar_drif_parse_subdevs(struct rcar_drif_sdr *sdr)
 	}
 
 	asd = v4l2_async_notifier_add_fwnode_subdev(notifier, fwnode,
-						    sizeof(*asd));
+						    struct v4l2_async_subdev);
 	fwnode_handle_put(fwnode);
 	if (IS_ERR(asd))
 		return PTR_ERR(asd);
diff --git a/drivers/media/platform/renesas-ceu.c b/drivers/media/platform/renesas-ceu.c
index 0298d08b39e4..1678175c49bd 100644
--- a/drivers/media/platform/renesas-ceu.c
+++ b/drivers/media/platform/renesas-ceu.c
@@ -1495,7 +1495,6 @@ static int ceu_parse_platform_data(struct ceu_device *ceudev,
 				   const struct ceu_platform_data *pdata)
 {
 	const struct ceu_async_subdev *async_sd;
-	struct v4l2_async_subdev *asd;
 	struct ceu_subdev *ceu_sd;
 	unsigned int i;
 	int ret;
@@ -1511,15 +1510,14 @@ static int ceu_parse_platform_data(struct ceu_device *ceudev,
 
 		/* Setup the ceu subdevice and the async subdevice. */
 		async_sd = &pdata->subdevs[i];
-		asd = v4l2_async_notifier_add_i2c_subdev(&ceudev->notifier,
+		ceu_sd = v4l2_async_notifier_add_i2c_subdev(&ceudev->notifier,
 				async_sd->i2c_adapter_id,
 				async_sd->i2c_address,
-				sizeof(*ceu_sd));
-		if (IS_ERR(asd)) {
+				struct ceu_subdev);
+		if (IS_ERR(ceu_sd)) {
 			v4l2_async_notifier_cleanup(&ceudev->notifier);
-			return PTR_ERR(asd);
+			return PTR_ERR(ceu_sd);
 		}
-		ceu_sd = to_ceu_subdev(asd);
 		ceu_sd->mbus_flags = async_sd->flags;
 		ceudev->subdevs[i] = ceu_sd;
 	}
@@ -1534,7 +1532,6 @@ static int ceu_parse_dt(struct ceu_device *ceudev)
 {
 	struct device_node *of = ceudev->dev->of_node;
 	struct device_node *ep;
-	struct v4l2_async_subdev *asd;
 	struct ceu_subdev *ceu_sd;
 	unsigned int i;
 	int num_ep;
@@ -1576,14 +1573,13 @@ static int ceu_parse_dt(struct ceu_device *ceudev)
 		}
 
 		/* Setup the ceu subdevice and the async subdevice. */
-		asd = v4l2_async_notifier_add_fwnode_remote_subdev(
+		ceu_sd = v4l2_async_notifier_add_fwnode_remote_subdev(
 				&ceudev->notifier, of_fwnode_handle(ep),
-				sizeof(*ceu_sd));
-		if (IS_ERR(asd)) {
-			ret = PTR_ERR(asd);
+				struct ceu_subdev);
+		if (IS_ERR(ceu_sd)) {
+			ret = PTR_ERR(ceu_sd);
 			goto error_cleanup;
 		}
-		ceu_sd = to_ceu_subdev(asd);
 		ceu_sd->mbus_flags = fw_ep.bus.parallel.flags;
 		ceudev->subdevs[i] = ceu_sd;
 
diff --git a/drivers/media/platform/rockchip/rkisp1/rkisp1-dev.c b/drivers/media/platform/rockchip/rkisp1/rkisp1-dev.c
index daa1b6d22436..02cde70a9d74 100644
--- a/drivers/media/platform/rockchip/rkisp1/rkisp1-dev.c
+++ b/drivers/media/platform/rockchip/rkisp1/rkisp1-dev.c
@@ -251,8 +251,7 @@ static int rkisp1_subdev_notifier(struct rkisp1_device *rkisp1)
 		struct v4l2_fwnode_endpoint vep = {
 			.bus_type = V4L2_MBUS_CSI2_DPHY
 		};
-		struct rkisp1_sensor_async *rk_asd = NULL;
-		struct v4l2_async_subdev *asd;
+		struct rkisp1_sensor_async *rk_asd;
 		struct fwnode_handle *ep;
 
 		ep = fwnode_graph_get_endpoint_by_id(dev_fwnode(rkisp1->dev),
@@ -265,14 +264,13 @@ static int rkisp1_subdev_notifier(struct rkisp1_device *rkisp1)
 		if (ret)
 			goto err_parse;
 
-		asd = v4l2_async_notifier_add_fwnode_remote_subdev(ntf, ep,
-							sizeof(*rk_asd));
-		if (IS_ERR(asd)) {
-			ret = PTR_ERR(asd);
+		rk_asd = v4l2_async_notifier_add_fwnode_remote_subdev(ntf, ep,
+							struct rkisp1_sensor_async);
+		if (IS_ERR(rk_asd)) {
+			ret = PTR_ERR(rk_asd);
 			goto err_parse;
 		}
 
-		rk_asd = container_of(asd, struct rkisp1_sensor_async, asd);
 		rk_asd->mbus_type = vep.bus_type;
 		rk_asd->mbus_flags = vep.bus.mipi_csi2.flags;
 		rk_asd->lanes = vep.bus.mipi_csi2.num_data_lanes;
diff --git a/drivers/media/platform/stm32/stm32-dcmi.c b/drivers/media/platform/stm32/stm32-dcmi.c
index 142f63d07dcd..bbcc2254fa2e 100644
--- a/drivers/media/platform/stm32/stm32-dcmi.c
+++ b/drivers/media/platform/stm32/stm32-dcmi.c
@@ -1820,7 +1820,8 @@ static int dcmi_graph_init(struct stm32_dcmi *dcmi)
 	v4l2_async_notifier_init(&dcmi->notifier);
 
 	asd = v4l2_async_notifier_add_fwnode_remote_subdev(
-		&dcmi->notifier, of_fwnode_handle(ep), sizeof(*asd));
+		&dcmi->notifier, of_fwnode_handle(ep),
+		struct v4l2_async_subdev);
 
 	of_node_put(ep);
 
diff --git a/drivers/media/platform/sunxi/sun4i-csi/sun4i_csi.c b/drivers/media/platform/sunxi/sun4i-csi/sun4i_csi.c
index 3f94b8c966f3..8d40a7acba9c 100644
--- a/drivers/media/platform/sunxi/sun4i-csi/sun4i_csi.c
+++ b/drivers/media/platform/sunxi/sun4i-csi/sun4i_csi.c
@@ -135,8 +135,8 @@ static int sun4i_csi_notifier_init(struct sun4i_csi *csi)
 
 	csi->bus = vep.bus.parallel;
 
-	asd = v4l2_async_notifier_add_fwnode_remote_subdev(&csi->notifier,
-							   ep, sizeof(*asd));
+	asd = v4l2_async_notifier_add_fwnode_remote_subdev(&csi->notifier, ep,
+							   struct v4l2_async_subdev);
 	if (IS_ERR(asd)) {
 		ret = PTR_ERR(asd);
 		goto out;
diff --git a/drivers/media/platform/ti-vpe/cal.c b/drivers/media/platform/ti-vpe/cal.c
index 5fb627811c6b..fa0931788040 100644
--- a/drivers/media/platform/ti-vpe/cal.c
+++ b/drivers/media/platform/ti-vpe/cal.c
@@ -685,23 +685,21 @@ static int cal_async_notifier_register(struct cal_dev *cal)
 	for (i = 0; i < cal->data->num_csi2_phy; ++i) {
 		struct cal_camerarx *phy = cal->phy[i];
 		struct cal_v4l2_async_subdev *casd;
-		struct v4l2_async_subdev *asd;
 		struct fwnode_handle *fwnode;
 
 		if (!phy->sensor_node)
 			continue;
 
 		fwnode = of_fwnode_handle(phy->sensor_node);
-		asd = v4l2_async_notifier_add_fwnode_subdev(&cal->notifier,
-							    fwnode,
-							    sizeof(*casd));
-		if (IS_ERR(asd)) {
+		casd = v4l2_async_notifier_add_fwnode_subdev(&cal->notifier,
+							     fwnode,
+							     struct cal_v4l2_async_subdev);
+		if (IS_ERR(casd)) {
 			phy_err(phy, "Failed to add subdev to notifier\n");
-			ret = PTR_ERR(asd);
+			ret = PTR_ERR(casd);
 			goto error;
 		}
 
-		casd = to_cal_asd(asd);
 		casd->phy = phy;
 	}
 
diff --git a/drivers/media/platform/video-mux.c b/drivers/media/platform/video-mux.c
index 7b280dfca727..133122e38515 100644
--- a/drivers/media/platform/video-mux.c
+++ b/drivers/media/platform/video-mux.c
@@ -371,7 +371,7 @@ static int video_mux_async_register(struct video_mux *vmux,
 			continue;
 
 		asd = v4l2_async_notifier_add_fwnode_remote_subdev(
-			&vmux->notifier, ep, sizeof(*asd));
+			&vmux->notifier, ep, struct v4l2_async_subdev);
 
 		fwnode_handle_put(ep);
 
diff --git a/drivers/media/platform/xilinx/xilinx-vipp.c b/drivers/media/platform/xilinx/xilinx-vipp.c
index cc2856efea59..bf4015d852e3 100644
--- a/drivers/media/platform/xilinx/xilinx-vipp.c
+++ b/drivers/media/platform/xilinx/xilinx-vipp.c
@@ -359,7 +359,7 @@ static int xvip_graph_parse_one(struct xvip_composite_device *xdev,
 	dev_dbg(xdev->dev, "parsing node %p\n", fwnode);
 
 	while (1) {
-		struct v4l2_async_subdev *asd;
+		struct xvip_graph_entity *xge;
 
 		ep = fwnode_graph_get_next_endpoint(fwnode, ep);
 		if (ep == NULL)
@@ -382,12 +382,12 @@ static int xvip_graph_parse_one(struct xvip_composite_device *xdev,
 			continue;
 		}
 
-		asd = v4l2_async_notifier_add_fwnode_subdev(
+		xge = v4l2_async_notifier_add_fwnode_subdev(
 			&xdev->notifier, remote,
-			sizeof(struct xvip_graph_entity));
+			struct xvip_graph_entity);
 		fwnode_handle_put(remote);
-		if (IS_ERR(asd)) {
-			ret = PTR_ERR(asd);
+		if (IS_ERR(xge)) {
+			ret = PTR_ERR(xge);
 			goto err_notifier_cleanup;
 		}
 	}
diff --git a/drivers/media/v4l2-core/v4l2-async.c b/drivers/media/v4l2-core/v4l2-async.c
index d848db962dc7..e638aa8aecb7 100644
--- a/drivers/media/v4l2-core/v4l2-async.c
+++ b/drivers/media/v4l2-core/v4l2-async.c
@@ -631,9 +631,9 @@ int __v4l2_async_notifier_add_subdev(struct v4l2_async_notifier *notifier,
 EXPORT_SYMBOL_GPL(__v4l2_async_notifier_add_subdev);
 
 struct v4l2_async_subdev *
-v4l2_async_notifier_add_fwnode_subdev(struct v4l2_async_notifier *notifier,
-				      struct fwnode_handle *fwnode,
-				      unsigned int asd_struct_size)
+__v4l2_async_notifier_add_fwnode_subdev(struct v4l2_async_notifier *notifier,
+					struct fwnode_handle *fwnode,
+					unsigned int asd_struct_size)
 {
 	struct v4l2_async_subdev *asd;
 	int ret;
@@ -654,12 +654,12 @@ v4l2_async_notifier_add_fwnode_subdev(struct v4l2_async_notifier *notifier,
 
 	return asd;
 }
-EXPORT_SYMBOL_GPL(v4l2_async_notifier_add_fwnode_subdev);
+EXPORT_SYMBOL_GPL(__v4l2_async_notifier_add_fwnode_subdev);
 
 struct v4l2_async_subdev *
-v4l2_async_notifier_add_fwnode_remote_subdev(struct v4l2_async_notifier *notif,
-					     struct fwnode_handle *endpoint,
-					     unsigned int asd_struct_size)
+__v4l2_async_notifier_add_fwnode_remote_subdev(struct v4l2_async_notifier *notif,
+					       struct fwnode_handle *endpoint,
+					       unsigned int asd_struct_size)
 {
 	struct v4l2_async_subdev *asd;
 	struct fwnode_handle *remote;
@@ -668,21 +668,21 @@ v4l2_async_notifier_add_fwnode_remote_subdev(struct v4l2_async_notifier *notif,
 	if (!remote)
 		return ERR_PTR(-ENOTCONN);
 
-	asd = v4l2_async_notifier_add_fwnode_subdev(notif, remote,
-						    asd_struct_size);
+	asd = __v4l2_async_notifier_add_fwnode_subdev(notif, remote,
+						      asd_struct_size);
 	/*
-	 * Calling v4l2_async_notifier_add_fwnode_subdev grabs a refcount,
+	 * Calling __v4l2_async_notifier_add_fwnode_subdev grabs a refcount,
 	 * so drop the one we got in fwnode_graph_get_remote_port_parent.
 	 */
 	fwnode_handle_put(remote);
 	return asd;
 }
-EXPORT_SYMBOL_GPL(v4l2_async_notifier_add_fwnode_remote_subdev);
+EXPORT_SYMBOL_GPL(__v4l2_async_notifier_add_fwnode_remote_subdev);
 
 struct v4l2_async_subdev *
-v4l2_async_notifier_add_i2c_subdev(struct v4l2_async_notifier *notifier,
-				   int adapter_id, unsigned short address,
-				   unsigned int asd_struct_size)
+__v4l2_async_notifier_add_i2c_subdev(struct v4l2_async_notifier *notifier,
+				     int adapter_id, unsigned short address,
+				     unsigned int asd_struct_size)
 {
 	struct v4l2_async_subdev *asd;
 	int ret;
@@ -703,7 +703,7 @@ v4l2_async_notifier_add_i2c_subdev(struct v4l2_async_notifier *notifier,
 
 	return asd;
 }
-EXPORT_SYMBOL_GPL(v4l2_async_notifier_add_i2c_subdev);
+EXPORT_SYMBOL_GPL(__v4l2_async_notifier_add_i2c_subdev);
 
 int v4l2_async_register_subdev(struct v4l2_subdev *sd)
 {
diff --git a/drivers/media/v4l2-core/v4l2-fwnode.c b/drivers/media/v4l2-core/v4l2-fwnode.c
index 63be16c8eb83..2283ff3b8e1d 100644
--- a/drivers/media/v4l2-core/v4l2-fwnode.c
+++ b/drivers/media/v4l2-core/v4l2-fwnode.c
@@ -944,7 +944,7 @@ static int v4l2_fwnode_reference_parse(struct device *dev,
 
 		asd = v4l2_async_notifier_add_fwnode_subdev(notifier,
 							    args.fwnode,
-							    sizeof(*asd));
+							    struct v4l2_async_subdev);
 		fwnode_handle_put(args.fwnode);
 		if (IS_ERR(asd)) {
 			/* not an error if asd already exists */
@@ -1244,7 +1244,7 @@ v4l2_fwnode_reference_parse_int_props(struct device *dev,
 		struct v4l2_async_subdev *asd;
 
 		asd = v4l2_async_notifier_add_fwnode_subdev(notifier, fwnode,
-							    sizeof(*asd));
+							    struct v4l2_async_subdev);
 		fwnode_handle_put(fwnode);
 		if (IS_ERR(asd)) {
 			ret = PTR_ERR(asd);
diff --git a/drivers/staging/media/imx/imx-media-csi.c b/drivers/staging/media/imx/imx-media-csi.c
index 6344389e6afa..ef5add079774 100644
--- a/drivers/staging/media/imx/imx-media-csi.c
+++ b/drivers/staging/media/imx/imx-media-csi.c
@@ -1923,7 +1923,7 @@ static int imx_csi_async_register(struct csi_priv *priv)
 					     FWNODE_GRAPH_ENDPOINT_NEXT);
 	if (ep) {
 		asd = v4l2_async_notifier_add_fwnode_remote_subdev(
-			&priv->notifier, ep, sizeof(*asd));
+			&priv->notifier, ep, struct v4l2_async_subdev);
 
 		fwnode_handle_put(ep);
 
diff --git a/drivers/staging/media/imx/imx-media-of.c b/drivers/staging/media/imx/imx-media-of.c
index 82e13e972e23..b677cf0e0c84 100644
--- a/drivers/staging/media/imx/imx-media-of.c
+++ b/drivers/staging/media/imx/imx-media-of.c
@@ -31,7 +31,7 @@ int imx_media_of_add_csi(struct imx_media_dev *imxmd,
 	/* add CSI fwnode to async notifier */
 	asd = v4l2_async_notifier_add_fwnode_subdev(&imxmd->notifier,
 						    of_fwnode_handle(csi_np),
-						    sizeof(*asd));
+						    struct v4l2_async_subdev);
 	if (IS_ERR(asd)) {
 		ret = PTR_ERR(asd);
 		if (ret == -EEXIST)
diff --git a/drivers/staging/media/imx/imx6-mipi-csi2.c b/drivers/staging/media/imx/imx6-mipi-csi2.c
index a79ab38158e2..4f8fcc91aaae 100644
--- a/drivers/staging/media/imx/imx6-mipi-csi2.c
+++ b/drivers/staging/media/imx/imx6-mipi-csi2.c
@@ -662,7 +662,7 @@ static int csi2_async_register(struct csi2_dev *csi2)
 	dev_dbg(csi2->dev, "flags: 0x%08x\n", vep.bus.mipi_csi2.flags);
 
 	asd = v4l2_async_notifier_add_fwnode_remote_subdev(
-		&csi2->notifier, ep, sizeof(*asd));
+		&csi2->notifier, ep, struct v4l2_async_subdev);
 	fwnode_handle_put(ep);
 
 	if (IS_ERR(asd))
diff --git a/drivers/staging/media/imx/imx7-media-csi.c b/drivers/staging/media/imx/imx7-media-csi.c
index 6c59485291ca..3046f880c014 100644
--- a/drivers/staging/media/imx/imx7-media-csi.c
+++ b/drivers/staging/media/imx/imx7-media-csi.c
@@ -1201,7 +1201,7 @@ static int imx7_csi_async_register(struct imx7_csi *csi)
 					     FWNODE_GRAPH_ENDPOINT_NEXT);
 	if (ep) {
 		asd = v4l2_async_notifier_add_fwnode_remote_subdev(
-			&csi->notifier, ep, sizeof(*asd));
+			&csi->notifier, ep, struct v4l2_async_subdev);
 
 		fwnode_handle_put(ep);
 
diff --git a/drivers/staging/media/imx/imx7-mipi-csis.c b/drivers/staging/media/imx/imx7-mipi-csis.c
index 1ba77e629e5b..a01a7364b4b9 100644
--- a/drivers/staging/media/imx/imx7-mipi-csis.c
+++ b/drivers/staging/media/imx/imx7-mipi-csis.c
@@ -1025,7 +1025,7 @@ static int mipi_csis_async_register(struct csi_state *state)
 	dev_dbg(state->dev, "flags: 0x%08x\n", state->bus.flags);
 
 	asd = v4l2_async_notifier_add_fwnode_remote_subdev(
-		&state->notifier, ep, sizeof(*asd));
+		&state->notifier, ep, struct v4l2_async_subdev);
 	if (IS_ERR(asd)) {
 		ret = PTR_ERR(asd);
 		goto err_parse;
diff --git a/drivers/staging/media/tegra-video/vi.c b/drivers/staging/media/tegra-video/vi.c
index 70e1e18644b2..7a09061cda57 100644
--- a/drivers/staging/media/tegra-video/vi.c
+++ b/drivers/staging/media/tegra-video/vi.c
@@ -1788,7 +1788,7 @@ static int tegra_vi_graph_parse_one(struct tegra_vi_channel *chan,
 	struct tegra_vi *vi = chan->vi;
 	struct fwnode_handle *ep = NULL;
 	struct fwnode_handle *remote = NULL;
-	struct v4l2_async_subdev *asd;
+	struct tegra_vi_graph_entity *tvge;
 	struct device_node *node = NULL;
 	int ret;
 
@@ -1812,10 +1812,10 @@ static int tegra_vi_graph_parse_one(struct tegra_vi_channel *chan,
 			continue;
 		}
 
-		asd = v4l2_async_notifier_add_fwnode_subdev(&chan->notifier,
-				remote, sizeof(struct tegra_vi_graph_entity));
-		if (IS_ERR(asd)) {
-			ret = PTR_ERR(asd);
+		tvge = v4l2_async_notifier_add_fwnode_subdev(&chan->notifier,
+				remote, struct tegra_vi_graph_entity);
+		if (IS_ERR(tvge)) {
+			ret = PTR_ERR(tvge);
 			dev_err(vi->dev,
 				"failed to add subdev to notifier: %d\n", ret);
 			fwnode_handle_put(remote);
diff --git a/include/media/v4l2-async.h b/include/media/v4l2-async.h
index b113329582ff..192a11bdc4ad 100644
--- a/include/media/v4l2-async.h
+++ b/include/media/v4l2-async.h
@@ -168,9 +168,12 @@ int __v4l2_async_notifier_add_subdev(struct v4l2_async_notifier *notifier,
  * is released later at notifier cleanup time.
  */
 struct v4l2_async_subdev *
-v4l2_async_notifier_add_fwnode_subdev(struct v4l2_async_notifier *notifier,
-				      struct fwnode_handle *fwnode,
-				      unsigned int asd_struct_size);
+__v4l2_async_notifier_add_fwnode_subdev(struct v4l2_async_notifier *notifier,
+					struct fwnode_handle *fwnode,
+					unsigned int asd_struct_size);
+#define v4l2_async_notifier_add_fwnode_subdev(__notifier, __fwnode, __type)	\
+((__type *)__v4l2_async_notifier_add_fwnode_subdev(__notifier, __fwnode,	\
+						   sizeof(__type)))
 
 /**
  * v4l2_async_notifier_add_fwnode_remote_subdev - Allocate and add a fwnode
@@ -194,9 +197,12 @@ v4l2_async_notifier_add_fwnode_subdev(struct v4l2_async_notifier *notifier,
  * exception that the fwnode refers to a local endpoint, not the remote one.
  */
 struct v4l2_async_subdev *
-v4l2_async_notifier_add_fwnode_remote_subdev(struct v4l2_async_notifier *notif,
-					     struct fwnode_handle *endpoint,
-					     unsigned int asd_struct_size);
+__v4l2_async_notifier_add_fwnode_remote_subdev(struct v4l2_async_notifier *notif,
+					       struct fwnode_handle *endpoint,
+					       unsigned int asd_struct_size);
+#define v4l2_async_notifier_add_fwnode_remote_subdev(__notifier, __ep, __type)	\
+((__type *)__v4l2_async_notifier_add_fwnode_remote_subdev(__notifier, __ep,	\
+							  sizeof(__type)))
 
 /**
  * v4l2_async_notifier_add_i2c_subdev - Allocate and add an i2c async
@@ -214,9 +220,12 @@ v4l2_async_notifier_add_fwnode_remote_subdev(struct v4l2_async_notifier *notif,
  * Same as above but for I2C matched sub-devices.
  */
 struct v4l2_async_subdev *
-v4l2_async_notifier_add_i2c_subdev(struct v4l2_async_notifier *notifier,
-				   int adapter_id, unsigned short address,
-				   unsigned int asd_struct_size);
+__v4l2_async_notifier_add_i2c_subdev(struct v4l2_async_notifier *notifier,
+				     int adapter_id, unsigned short address,
+				     unsigned int asd_struct_size);
+#define v4l2_async_notifier_add_i2c_subdev(__notifier, __adap, __addr, __type)	\
+((__type *)__v4l2_async_notifier_add_i2c_subdev(__notifier, __adap, __addr,	\
+						sizeof(__type)))
 
 /**
  * v4l2_async_notifier_register - registers a subdevice asynchronous notifier
-- 
2.29.2


^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCH v5 13/13] media: Clarify v4l2-async subdevice addition API
  2021-02-02 13:55 [PATCH v5 00/13] V4L2 Async notifier API cleanup Sakari Ailus
                   ` (11 preceding siblings ...)
  2021-02-02 13:56 ` [PATCH v5 12/13] media: v4l2-async: Improve v4l2_async_notifier_add_*_subdev() API Sakari Ailus
@ 2021-02-02 13:56 ` Sakari Ailus
  2021-02-02 14:01   ` Helen Koike
                     ` (2 more replies)
  12 siblings, 3 replies; 25+ messages in thread
From: Sakari Ailus @ 2021-02-02 13:56 UTC (permalink / raw)
  To: linux-media
  Cc: Hans Verkuil, kernel, Laurent Pinchart, Kieran Bingham,
	Jacopo Mondi, niklas.soderlund+renesas, Helen Koike,
	Dafna Hirschfeld, Hugues Fruchet, Nicolas Ferre, Yong Zhi,
	Sylwester Nawrocki, Maxime Ripard, Robert Foss, Philipp Zabel,
	Ezequiel Garcia

From: Ezequiel Garcia <ezequiel@collabora.com>

Now that most users of v4l2_async_notifier_add_subdev have been converted,
let's fix the documentation so it's more clear how the v4l2-async API
should be used.

Document functions that drivers should use, and their purpose.

Signed-off-by: Ezequiel Garcia <ezequiel@collabora.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
---
 .../driver-api/media/v4l2-subdev.rst          | 48 +++++++++++++++----
 include/media/v4l2-async.h                    | 15 ++++--
 2 files changed, 50 insertions(+), 13 deletions(-)

diff --git a/Documentation/driver-api/media/v4l2-subdev.rst b/Documentation/driver-api/media/v4l2-subdev.rst
index 0e82c77cf3e2..8b53da2f9c74 100644
--- a/Documentation/driver-api/media/v4l2-subdev.rst
+++ b/Documentation/driver-api/media/v4l2-subdev.rst
@@ -197,15 +197,45 @@ unregister the notifier the driver has to call
 takes two arguments: a pointer to struct :c:type:`v4l2_device` and a
 pointer to struct :c:type:`v4l2_async_notifier`.
 
-Before registering the notifier, bridge drivers must do two things:
-first, the notifier must be initialized using the
-:c:func:`v4l2_async_notifier_init`. Second, bridge drivers can then
-begin to form a list of subdevice descriptors that the bridge device
-needs for its operation. Subdevice descriptors are added to the notifier
-using the :c:func:`v4l2_async_notifier_add_subdev` call. This function
-takes two arguments: a pointer to struct :c:type:`v4l2_async_notifier`,
-and a pointer to the subdevice descripter, which is of type struct
-:c:type:`v4l2_async_subdev`.
+Before registering the notifier, bridge drivers must do two things: first, the
+notifier must be initialized using the :c:func:`v4l2_async_notifier_init`.
+Second, bridge drivers can then begin to form a list of subdevice descriptors
+that the bridge device needs for its operation. Several functions are available
+to add subdevice descriptors to a notifier, depending on the type of device and
+the needs of the driver.
+
+:c:func:`v4l2_async_notifier_add_fwnode_remote_subdev` and
+:c:func:`v4l2_async_notifier_add_i2c_subdev` are for bridge and ISP drivers for
+registering their async sub-devices with the notifier.
+
+:c:func:`v4l2_async_register_subdev_sensor_common` is a helper function for
+sensor drivers registering their own async sub-device, but it also registers a
+notifier and further registers async sub-devices for lens and flash devices
+found in firmware. The notifier for the sub-device is unregistered with the
+async sub-device.
+
+These functions allocate an async sub-device descriptor which is of type struct
+:c:type:`v4l2_async_subdev` embedded in a driver-specific struct. The &struct
+:c:type:`v4l2_async_subdev` shall be the first member of this struct:
+
+.. code-block:: c
+
+	struct my_async_subdev {
+		struct v4l2_async_subdev asd;
+		...
+	};
+
+	struct my_async_subdev *my_asd;
+	struct fwnode_handle *ep;
+
+	...
+
+	my_asd = v4l2_async_notifier_add_fwnode_remote_subdev(&notifier, ep,
+							      struct my_async_subdev);
+	fwnode_handle_put(ep);
+
+	if (IS_ERR(asd))
+		return PTR_ERR(asd);
 
 The V4L2 core will then use these descriptors to match asynchronously
 registered subdevices to them. If a match is detected the ``.bound()``
diff --git a/include/media/v4l2-async.h b/include/media/v4l2-async.h
index 192a11bdc4ad..6dac6cb6290f 100644
--- a/include/media/v4l2-async.h
+++ b/include/media/v4l2-async.h
@@ -128,7 +128,12 @@ void v4l2_async_debug_init(struct dentry *debugfs_dir);
  * @notifier: pointer to &struct v4l2_async_notifier
  *
  * This function initializes the notifier @asd_list. It must be called
- * before the first call to @v4l2_async_notifier_add_subdev.
+ * before adding a subdevice to a notifier, using one of:
+ * @v4l2_async_notifier_add_fwnode_remote_subdev,
+ * @v4l2_async_notifier_add_fwnode_subdev,
+ * @v4l2_async_notifier_add_i2c_subdev,
+ * @v4l2_async_notifier_add_subdev or
+ * @v4l2_async_notifier_parse_fwnode_endpoints.
  */
 void v4l2_async_notifier_init(struct v4l2_async_notifier *notifier);
 
@@ -262,9 +267,11 @@ void v4l2_async_notifier_unregister(struct v4l2_async_notifier *notifier);
  * 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_add_subdev,
- * @v4l2_async_notifier_parse_fwnode_endpoints or
- * @v4l2_fwnode_reference_parse_sensor_common.
+ * @v4l2_async_notifier_add_fwnode_remote_subdev,
+ * @v4l2_async_notifier_add_fwnode_subdev,
+ * @v4l2_async_notifier_add_i2c_subdev,
+ * @v4l2_async_notifier_add_subdev or
+ * @v4l2_async_notifier_parse_fwnode_endpoints.
  *
  * 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
-- 
2.29.2


^ permalink raw reply related	[flat|nested] 25+ messages in thread

* Re: [PATCH v5 13/13] media: Clarify v4l2-async subdevice addition API
  2021-02-02 13:56 ` [PATCH v5 13/13] media: Clarify v4l2-async subdevice addition API Sakari Ailus
@ 2021-02-02 14:01   ` Helen Koike
  2021-02-02 14:19     ` Sakari Ailus
  2021-02-02 14:25   ` [PATCH v5.1 " Sakari Ailus
  2021-02-06  8:29   ` [PATCH v5 " Mauro Carvalho Chehab
  2 siblings, 1 reply; 25+ messages in thread
From: Helen Koike @ 2021-02-02 14:01 UTC (permalink / raw)
  To: Sakari Ailus, linux-media
  Cc: Hans Verkuil, kernel, Laurent Pinchart, Kieran Bingham,
	Jacopo Mondi, niklas.soderlund+renesas, Dafna Hirschfeld,
	Hugues Fruchet, Nicolas Ferre, Yong Zhi, Sylwester Nawrocki,
	Maxime Ripard, Robert Foss, Philipp Zabel, Ezequiel Garcia

Hi Sakari,

On 2/2/21 10:56 AM, Sakari Ailus wrote:
> From: Ezequiel Garcia <ezequiel@collabora.com>
> 
> Now that most users of v4l2_async_notifier_add_subdev have been converted,
> let's fix the documentation so it's more clear how the v4l2-async API
> should be used.
> 
> Document functions that drivers should use, and their purpose.
> 
> Signed-off-by: Ezequiel Garcia <ezequiel@collabora.com>
> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
> Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
> ---
>  .../driver-api/media/v4l2-subdev.rst          | 48 +++++++++++++++----
>  include/media/v4l2-async.h                    | 15 ++++--
>  2 files changed, 50 insertions(+), 13 deletions(-)
> 
> diff --git a/Documentation/driver-api/media/v4l2-subdev.rst b/Documentation/driver-api/media/v4l2-subdev.rst
> index 0e82c77cf3e2..8b53da2f9c74 100644
> --- a/Documentation/driver-api/media/v4l2-subdev.rst
> +++ b/Documentation/driver-api/media/v4l2-subdev.rst
> @@ -197,15 +197,45 @@ unregister the notifier the driver has to call
>  takes two arguments: a pointer to struct :c:type:`v4l2_device` and a
>  pointer to struct :c:type:`v4l2_async_notifier`.
>  
> -Before registering the notifier, bridge drivers must do two things:
> -first, the notifier must be initialized using the
> -:c:func:`v4l2_async_notifier_init`. Second, bridge drivers can then
> -begin to form a list of subdevice descriptors that the bridge device
> -needs for its operation. Subdevice descriptors are added to the notifier
> -using the :c:func:`v4l2_async_notifier_add_subdev` call. This function
> -takes two arguments: a pointer to struct :c:type:`v4l2_async_notifier`,
> -and a pointer to the subdevice descripter, which is of type struct
> -:c:type:`v4l2_async_subdev`.
> +Before registering the notifier, bridge drivers must do two things: first, the
> +notifier must be initialized using the :c:func:`v4l2_async_notifier_init`.
> +Second, bridge drivers can then begin to form a list of subdevice descriptors
> +that the bridge device needs for its operation. Several functions are available
> +to add subdevice descriptors to a notifier, depending on the type of device and
> +the needs of the driver.
> +
> +:c:func:`v4l2_async_notifier_add_fwnode_remote_subdev` and
> +:c:func:`v4l2_async_notifier_add_i2c_subdev` are for bridge and ISP drivers for
> +registering their async sub-devices with the notifier.
> +
> +:c:func:`v4l2_async_register_subdev_sensor_common` is a helper function for
> +sensor drivers registering their own async sub-device, but it also registers a
> +notifier and further registers async sub-devices for lens and flash devices
> +found in firmware. The notifier for the sub-device is unregistered with the
> +async sub-device.
> +
> +These functions allocate an async sub-device descriptor which is of type struct
> +:c:type:`v4l2_async_subdev` embedded in a driver-specific struct. The &struct
> +:c:type:`v4l2_async_subdev` shall be the first member of this struct:
> +
> +.. code-block:: c
> +
> +	struct my_async_subdev {
> +		struct v4l2_async_subdev asd;
> +		...
> +	};
> +
> +	struct my_async_subdev *my_asd;
> +	struct fwnode_handle *ep;
> +
> +	...
> +
> +	my_asd = v4l2_async_notifier_add_fwnode_remote_subdev(&notifier, ep,
> +							      struct my_async_subdev);
> +	fwnode_handle_put(ep);
> +
> +	if (IS_ERR(asd))
> +		return PTR_ERR(asd);
>  
>  The V4L2 core will then use these descriptors to match asynchronously
>  registered subdevices to them. If a match is detected the ``.bound()``
> diff --git a/include/media/v4l2-async.h b/include/media/v4l2-async.h
> index 192a11bdc4ad..6dac6cb6290f 100644
> --- a/include/media/v4l2-async.h
> +++ b/include/media/v4l2-async.h
> @@ -128,7 +128,12 @@ void v4l2_async_debug_init(struct dentry *debugfs_dir);
>   * @notifier: pointer to &struct v4l2_async_notifier
>   *
>   * This function initializes the notifier @asd_list. It must be called
> - * before the first call to @v4l2_async_notifier_add_subdev.
> + * before adding a subdevice to a notifier, using one of:
> + * @v4l2_async_notifier_add_fwnode_remote_subdev,
> + * @v4l2_async_notifier_add_fwnode_subdev,
> + * @v4l2_async_notifier_add_i2c_subdev,
> + * @v4l2_async_notifier_add_subdev or

s/v4l2_async_notifier_add_subdev/__v4l2_async_notifier_add_subdev no? Since
it got renamed on patch 11/13, or am I missing something?

> + * @v4l2_async_notifier_parse_fwnode_endpoints.

Should we mention this is deprecated? maybe just a parenthesis "(deprecated)"

>   */
>  void v4l2_async_notifier_init(struct v4l2_async_notifier *notifier);
>  
> @@ -262,9 +267,11 @@ void v4l2_async_notifier_unregister(struct v4l2_async_notifier *notifier);
>   * 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_add_subdev,
> - * @v4l2_async_notifier_parse_fwnode_endpoints or
> - * @v4l2_fwnode_reference_parse_sensor_common.
> + * @v4l2_async_notifier_add_fwnode_remote_subdev,
> + * @v4l2_async_notifier_add_fwnode_subdev,
> + * @v4l2_async_notifier_add_i2c_subdev,
> + * @v4l2_async_notifier_add_subdev or

Same here.

Regards,
Helen

> + * @v4l2_async_notifier_parse_fwnode_endpoints.
>   *
>   * 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
> 

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH v5 13/13] media: Clarify v4l2-async subdevice addition API
  2021-02-02 14:01   ` Helen Koike
@ 2021-02-02 14:19     ` Sakari Ailus
  0 siblings, 0 replies; 25+ messages in thread
From: Sakari Ailus @ 2021-02-02 14:19 UTC (permalink / raw)
  To: Helen Koike
  Cc: linux-media, Hans Verkuil, kernel, Laurent Pinchart,
	Kieran Bingham, Jacopo Mondi, niklas.soderlund+renesas,
	Dafna Hirschfeld, Hugues Fruchet, Nicolas Ferre, Yong Zhi,
	Sylwester Nawrocki, Maxime Ripard, Robert Foss, Philipp Zabel,
	Ezequiel Garcia

On Tue, Feb 02, 2021 at 11:01:21AM -0300, Helen Koike wrote:
> Hi Sakari,
> 
> On 2/2/21 10:56 AM, Sakari Ailus wrote:
> > From: Ezequiel Garcia <ezequiel@collabora.com>
> > 
> > Now that most users of v4l2_async_notifier_add_subdev have been converted,
> > let's fix the documentation so it's more clear how the v4l2-async API
> > should be used.
> > 
> > Document functions that drivers should use, and their purpose.
> > 
> > Signed-off-by: Ezequiel Garcia <ezequiel@collabora.com>
> > Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
> > Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
> > ---
> >  .../driver-api/media/v4l2-subdev.rst          | 48 +++++++++++++++----
> >  include/media/v4l2-async.h                    | 15 ++++--
> >  2 files changed, 50 insertions(+), 13 deletions(-)
> > 
> > diff --git a/Documentation/driver-api/media/v4l2-subdev.rst b/Documentation/driver-api/media/v4l2-subdev.rst
> > index 0e82c77cf3e2..8b53da2f9c74 100644
> > --- a/Documentation/driver-api/media/v4l2-subdev.rst
> > +++ b/Documentation/driver-api/media/v4l2-subdev.rst
> > @@ -197,15 +197,45 @@ unregister the notifier the driver has to call
> >  takes two arguments: a pointer to struct :c:type:`v4l2_device` and a
> >  pointer to struct :c:type:`v4l2_async_notifier`.
> >  
> > -Before registering the notifier, bridge drivers must do two things:
> > -first, the notifier must be initialized using the
> > -:c:func:`v4l2_async_notifier_init`. Second, bridge drivers can then
> > -begin to form a list of subdevice descriptors that the bridge device
> > -needs for its operation. Subdevice descriptors are added to the notifier
> > -using the :c:func:`v4l2_async_notifier_add_subdev` call. This function
> > -takes two arguments: a pointer to struct :c:type:`v4l2_async_notifier`,
> > -and a pointer to the subdevice descripter, which is of type struct
> > -:c:type:`v4l2_async_subdev`.
> > +Before registering the notifier, bridge drivers must do two things: first, the
> > +notifier must be initialized using the :c:func:`v4l2_async_notifier_init`.
> > +Second, bridge drivers can then begin to form a list of subdevice descriptors
> > +that the bridge device needs for its operation. Several functions are available
> > +to add subdevice descriptors to a notifier, depending on the type of device and
> > +the needs of the driver.
> > +
> > +:c:func:`v4l2_async_notifier_add_fwnode_remote_subdev` and
> > +:c:func:`v4l2_async_notifier_add_i2c_subdev` are for bridge and ISP drivers for
> > +registering their async sub-devices with the notifier.
> > +
> > +:c:func:`v4l2_async_register_subdev_sensor_common` is a helper function for
> > +sensor drivers registering their own async sub-device, but it also registers a
> > +notifier and further registers async sub-devices for lens and flash devices
> > +found in firmware. The notifier for the sub-device is unregistered with the
> > +async sub-device.
> > +
> > +These functions allocate an async sub-device descriptor which is of type struct
> > +:c:type:`v4l2_async_subdev` embedded in a driver-specific struct. The &struct
> > +:c:type:`v4l2_async_subdev` shall be the first member of this struct:
> > +
> > +.. code-block:: c
> > +
> > +	struct my_async_subdev {
> > +		struct v4l2_async_subdev asd;
> > +		...
> > +	};
> > +
> > +	struct my_async_subdev *my_asd;
> > +	struct fwnode_handle *ep;
> > +
> > +	...
> > +
> > +	my_asd = v4l2_async_notifier_add_fwnode_remote_subdev(&notifier, ep,
> > +							      struct my_async_subdev);
> > +	fwnode_handle_put(ep);
> > +
> > +	if (IS_ERR(asd))
> > +		return PTR_ERR(asd);
> >  
> >  The V4L2 core will then use these descriptors to match asynchronously
> >  registered subdevices to them. If a match is detected the ``.bound()``
> > diff --git a/include/media/v4l2-async.h b/include/media/v4l2-async.h
> > index 192a11bdc4ad..6dac6cb6290f 100644
> > --- a/include/media/v4l2-async.h
> > +++ b/include/media/v4l2-async.h
> > @@ -128,7 +128,12 @@ void v4l2_async_debug_init(struct dentry *debugfs_dir);
> >   * @notifier: pointer to &struct v4l2_async_notifier
> >   *
> >   * This function initializes the notifier @asd_list. It must be called
> > - * before the first call to @v4l2_async_notifier_add_subdev.
> > + * before adding a subdevice to a notifier, using one of:
> > + * @v4l2_async_notifier_add_fwnode_remote_subdev,
> > + * @v4l2_async_notifier_add_fwnode_subdev,
> > + * @v4l2_async_notifier_add_i2c_subdev,
> > + * @v4l2_async_notifier_add_subdev or
> 
> s/v4l2_async_notifier_add_subdev/__v4l2_async_notifier_add_subdev no? Since
> it got renamed on patch 11/13, or am I missing something?

Ooops... forgot this one.

> 
> > + * @v4l2_async_notifier_parse_fwnode_endpoints.
> 
> Should we mention this is deprecated? maybe just a parenthesis "(deprecated)"

That is mentioned in the documentation of that function, should be fine
without here.

> 
> >   */
> >  void v4l2_async_notifier_init(struct v4l2_async_notifier *notifier);
> >  
> > @@ -262,9 +267,11 @@ void v4l2_async_notifier_unregister(struct v4l2_async_notifier *notifier);
> >   * 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_add_subdev,
> > - * @v4l2_async_notifier_parse_fwnode_endpoints or
> > - * @v4l2_fwnode_reference_parse_sensor_common.
> > + * @v4l2_async_notifier_add_fwnode_remote_subdev,
> > + * @v4l2_async_notifier_add_fwnode_subdev,
> > + * @v4l2_async_notifier_add_i2c_subdev,
> > + * @v4l2_async_notifier_add_subdev or
> 
> Same here.
> 
> Regards,
> Helen
> 
> > + * @v4l2_async_notifier_parse_fwnode_endpoints.
> >   *
> >   * 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
> > 

-- 
Sakari Ailus

^ permalink raw reply	[flat|nested] 25+ messages in thread

* [PATCH v5.1 13/13] media: Clarify v4l2-async subdevice addition API
  2021-02-02 13:56 ` [PATCH v5 13/13] media: Clarify v4l2-async subdevice addition API Sakari Ailus
  2021-02-02 14:01   ` Helen Koike
@ 2021-02-02 14:25   ` Sakari Ailus
  2021-02-02 15:23     ` Helen Koike
  2021-02-06  8:29   ` [PATCH v5 " Mauro Carvalho Chehab
  2 siblings, 1 reply; 25+ messages in thread
From: Sakari Ailus @ 2021-02-02 14:25 UTC (permalink / raw)
  To: linux-media
  Cc: Hans Verkuil, kernel, Laurent Pinchart, Kieran Bingham,
	Jacopo Mondi, niklas.soderlund+renesas, Helen Koike,
	Dafna Hirschfeld, Hugues Fruchet, Nicolas Ferre, Yong Zhi,
	Sylwester Nawrocki, Maxime Ripard, Robert Foss, Philipp Zabel,
	Ezequiel Garcia

From: Ezequiel Garcia <ezequiel@collabora.com>

Now that most users of v4l2_async_notifier_add_subdev have been converted,
let's fix the documentation so it's more clear how the v4l2-async API
should be used.

Document functions that drivers should use, and their purpose.

Signed-off-by: Ezequiel Garcia <ezequiel@collabora.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
---
since v5:

- Fix function names after which notifier needs to be cleaned up or
  initialised before; v4l2_async_notifier_add_subdev ->
  __v4l2_async_notifier_add_subdev.

 .../driver-api/media/v4l2-subdev.rst          | 48 +++++++++++++++----
 include/media/v4l2-async.h                    | 15 ++++--
 2 files changed, 50 insertions(+), 13 deletions(-)

diff --git a/Documentation/driver-api/media/v4l2-subdev.rst b/Documentation/driver-api/media/v4l2-subdev.rst
index 0e82c77cf3e2..8b53da2f9c74 100644
--- a/Documentation/driver-api/media/v4l2-subdev.rst
+++ b/Documentation/driver-api/media/v4l2-subdev.rst
@@ -197,15 +197,45 @@ unregister the notifier the driver has to call
 takes two arguments: a pointer to struct :c:type:`v4l2_device` and a
 pointer to struct :c:type:`v4l2_async_notifier`.
 
-Before registering the notifier, bridge drivers must do two things:
-first, the notifier must be initialized using the
-:c:func:`v4l2_async_notifier_init`. Second, bridge drivers can then
-begin to form a list of subdevice descriptors that the bridge device
-needs for its operation. Subdevice descriptors are added to the notifier
-using the :c:func:`v4l2_async_notifier_add_subdev` call. This function
-takes two arguments: a pointer to struct :c:type:`v4l2_async_notifier`,
-and a pointer to the subdevice descripter, which is of type struct
-:c:type:`v4l2_async_subdev`.
+Before registering the notifier, bridge drivers must do two things: first, the
+notifier must be initialized using the :c:func:`v4l2_async_notifier_init`.
+Second, bridge drivers can then begin to form a list of subdevice descriptors
+that the bridge device needs for its operation. Several functions are available
+to add subdevice descriptors to a notifier, depending on the type of device and
+the needs of the driver.
+
+:c:func:`v4l2_async_notifier_add_fwnode_remote_subdev` and
+:c:func:`v4l2_async_notifier_add_i2c_subdev` are for bridge and ISP drivers for
+registering their async sub-devices with the notifier.
+
+:c:func:`v4l2_async_register_subdev_sensor_common` is a helper function for
+sensor drivers registering their own async sub-device, but it also registers a
+notifier and further registers async sub-devices for lens and flash devices
+found in firmware. The notifier for the sub-device is unregistered with the
+async sub-device.
+
+These functions allocate an async sub-device descriptor which is of type struct
+:c:type:`v4l2_async_subdev` embedded in a driver-specific struct. The &struct
+:c:type:`v4l2_async_subdev` shall be the first member of this struct:
+
+.. code-block:: c
+
+	struct my_async_subdev {
+		struct v4l2_async_subdev asd;
+		...
+	};
+
+	struct my_async_subdev *my_asd;
+	struct fwnode_handle *ep;
+
+	...
+
+	my_asd = v4l2_async_notifier_add_fwnode_remote_subdev(&notifier, ep,
+							      struct my_async_subdev);
+	fwnode_handle_put(ep);
+
+	if (IS_ERR(asd))
+		return PTR_ERR(asd);
 
 The V4L2 core will then use these descriptors to match asynchronously
 registered subdevices to them. If a match is detected the ``.bound()``
diff --git a/include/media/v4l2-async.h b/include/media/v4l2-async.h
index 192a11bdc4ad..6f22daa6f067 100644
--- a/include/media/v4l2-async.h
+++ b/include/media/v4l2-async.h
@@ -128,7 +128,12 @@ void v4l2_async_debug_init(struct dentry *debugfs_dir);
  * @notifier: pointer to &struct v4l2_async_notifier
  *
  * This function initializes the notifier @asd_list. It must be called
- * before the first call to @v4l2_async_notifier_add_subdev.
+ * before adding a subdevice to a notifier, using one of:
+ * @v4l2_async_notifier_add_fwnode_remote_subdev,
+ * @v4l2_async_notifier_add_fwnode_subdev,
+ * @v4l2_async_notifier_add_i2c_subdev,
+ * @__v4l2_async_notifier_add_subdev or
+ * @v4l2_async_notifier_parse_fwnode_endpoints.
  */
 void v4l2_async_notifier_init(struct v4l2_async_notifier *notifier);
 
@@ -262,9 +267,11 @@ void v4l2_async_notifier_unregister(struct v4l2_async_notifier *notifier);
  * 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_add_subdev,
- * @v4l2_async_notifier_parse_fwnode_endpoints or
- * @v4l2_fwnode_reference_parse_sensor_common.
+ * @v4l2_async_notifier_add_fwnode_remote_subdev,
+ * @v4l2_async_notifier_add_fwnode_subdev,
+ * @v4l2_async_notifier_add_i2c_subdev,
+ * @__v4l2_async_notifier_add_subdev or
+ * @v4l2_async_notifier_parse_fwnode_endpoints.
  *
  * 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
-- 
2.29.2


^ permalink raw reply related	[flat|nested] 25+ messages in thread

* Re: [PATCH v5.1 13/13] media: Clarify v4l2-async subdevice addition API
  2021-02-02 14:25   ` [PATCH v5.1 " Sakari Ailus
@ 2021-02-02 15:23     ` Helen Koike
  2021-02-02 18:15       ` Sakari Ailus
  0 siblings, 1 reply; 25+ messages in thread
From: Helen Koike @ 2021-02-02 15:23 UTC (permalink / raw)
  To: Sakari Ailus, linux-media
  Cc: Hans Verkuil, kernel, Laurent Pinchart, Kieran Bingham,
	Jacopo Mondi, niklas.soderlund+renesas, Dafna Hirschfeld,
	Hugues Fruchet, Nicolas Ferre, Yong Zhi, Sylwester Nawrocki,
	Maxime Ripard, Robert Foss, Philipp Zabel, Ezequiel Garcia



On 2/2/21 11:25 AM, Sakari Ailus wrote:
> From: Ezequiel Garcia <ezequiel@collabora.com>
> 
> Now that most users of v4l2_async_notifier_add_subdev have been converted,
> let's fix the documentation so it's more clear how the v4l2-async API
> should be used.
> 
> Document functions that drivers should use, and their purpose.
> 
> Signed-off-by: Ezequiel Garcia <ezequiel@collabora.com>
> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
> Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>

Reviewed-by: Helen Koike <helen.koike@collabora.com>

Thanks for working on this :)

Regards,
Helen

> ---
> since v5:
> 
> - Fix function names after which notifier needs to be cleaned up or
>   initialised before; v4l2_async_notifier_add_subdev ->
>   __v4l2_async_notifier_add_subdev.
> 
>  .../driver-api/media/v4l2-subdev.rst          | 48 +++++++++++++++----
>  include/media/v4l2-async.h                    | 15 ++++--
>  2 files changed, 50 insertions(+), 13 deletions(-)
> 
> diff --git a/Documentation/driver-api/media/v4l2-subdev.rst b/Documentation/driver-api/media/v4l2-subdev.rst
> index 0e82c77cf3e2..8b53da2f9c74 100644
> --- a/Documentation/driver-api/media/v4l2-subdev.rst
> +++ b/Documentation/driver-api/media/v4l2-subdev.rst
> @@ -197,15 +197,45 @@ unregister the notifier the driver has to call
>  takes two arguments: a pointer to struct :c:type:`v4l2_device` and a
>  pointer to struct :c:type:`v4l2_async_notifier`.
>  
> -Before registering the notifier, bridge drivers must do two things:
> -first, the notifier must be initialized using the
> -:c:func:`v4l2_async_notifier_init`. Second, bridge drivers can then
> -begin to form a list of subdevice descriptors that the bridge device
> -needs for its operation. Subdevice descriptors are added to the notifier
> -using the :c:func:`v4l2_async_notifier_add_subdev` call. This function
> -takes two arguments: a pointer to struct :c:type:`v4l2_async_notifier`,
> -and a pointer to the subdevice descripter, which is of type struct
> -:c:type:`v4l2_async_subdev`.
> +Before registering the notifier, bridge drivers must do two things: first, the
> +notifier must be initialized using the :c:func:`v4l2_async_notifier_init`.
> +Second, bridge drivers can then begin to form a list of subdevice descriptors
> +that the bridge device needs for its operation. Several functions are available
> +to add subdevice descriptors to a notifier, depending on the type of device and
> +the needs of the driver.
> +
> +:c:func:`v4l2_async_notifier_add_fwnode_remote_subdev` and
> +:c:func:`v4l2_async_notifier_add_i2c_subdev` are for bridge and ISP drivers for
> +registering their async sub-devices with the notifier.
> +
> +:c:func:`v4l2_async_register_subdev_sensor_common` is a helper function for
> +sensor drivers registering their own async sub-device, but it also registers a
> +notifier and further registers async sub-devices for lens and flash devices
> +found in firmware. The notifier for the sub-device is unregistered with the
> +async sub-device.
> +
> +These functions allocate an async sub-device descriptor which is of type struct
> +:c:type:`v4l2_async_subdev` embedded in a driver-specific struct. The &struct
> +:c:type:`v4l2_async_subdev` shall be the first member of this struct:
> +
> +.. code-block:: c
> +
> +	struct my_async_subdev {
> +		struct v4l2_async_subdev asd;
> +		...
> +	};
> +
> +	struct my_async_subdev *my_asd;
> +	struct fwnode_handle *ep;
> +
> +	...
> +
> +	my_asd = v4l2_async_notifier_add_fwnode_remote_subdev(&notifier, ep,
> +							      struct my_async_subdev);
> +	fwnode_handle_put(ep);
> +
> +	if (IS_ERR(asd))
> +		return PTR_ERR(asd);
>  
>  The V4L2 core will then use these descriptors to match asynchronously
>  registered subdevices to them. If a match is detected the ``.bound()``
> diff --git a/include/media/v4l2-async.h b/include/media/v4l2-async.h
> index 192a11bdc4ad..6f22daa6f067 100644
> --- a/include/media/v4l2-async.h
> +++ b/include/media/v4l2-async.h
> @@ -128,7 +128,12 @@ void v4l2_async_debug_init(struct dentry *debugfs_dir);
>   * @notifier: pointer to &struct v4l2_async_notifier
>   *
>   * This function initializes the notifier @asd_list. It must be called
> - * before the first call to @v4l2_async_notifier_add_subdev.
> + * before adding a subdevice to a notifier, using one of:
> + * @v4l2_async_notifier_add_fwnode_remote_subdev,
> + * @v4l2_async_notifier_add_fwnode_subdev,
> + * @v4l2_async_notifier_add_i2c_subdev,
> + * @__v4l2_async_notifier_add_subdev or
> + * @v4l2_async_notifier_parse_fwnode_endpoints.
>   */
>  void v4l2_async_notifier_init(struct v4l2_async_notifier *notifier);
>  
> @@ -262,9 +267,11 @@ void v4l2_async_notifier_unregister(struct v4l2_async_notifier *notifier);
>   * 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_add_subdev,
> - * @v4l2_async_notifier_parse_fwnode_endpoints or
> - * @v4l2_fwnode_reference_parse_sensor_common.
> + * @v4l2_async_notifier_add_fwnode_remote_subdev,
> + * @v4l2_async_notifier_add_fwnode_subdev,
> + * @v4l2_async_notifier_add_i2c_subdev,
> + * @__v4l2_async_notifier_add_subdev or
> + * @v4l2_async_notifier_parse_fwnode_endpoints.
>   *
>   * 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
> 

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH v5.1 13/13] media: Clarify v4l2-async subdevice addition API
  2021-02-02 15:23     ` Helen Koike
@ 2021-02-02 18:15       ` Sakari Ailus
  0 siblings, 0 replies; 25+ messages in thread
From: Sakari Ailus @ 2021-02-02 18:15 UTC (permalink / raw)
  To: Helen Koike
  Cc: linux-media, Hans Verkuil, kernel, Laurent Pinchart,
	Kieran Bingham, Jacopo Mondi, niklas.soderlund+renesas,
	Dafna Hirschfeld, Hugues Fruchet, Nicolas Ferre, Yong Zhi,
	Sylwester Nawrocki, Maxime Ripard, Robert Foss, Philipp Zabel,
	Ezequiel Garcia

On Tue, Feb 02, 2021 at 12:23:52PM -0300, Helen Koike wrote:
> 
> 
> On 2/2/21 11:25 AM, Sakari Ailus wrote:
> > From: Ezequiel Garcia <ezequiel@collabora.com>
> > 
> > Now that most users of v4l2_async_notifier_add_subdev have been converted,
> > let's fix the documentation so it's more clear how the v4l2-async API
> > should be used.
> > 
> > Document functions that drivers should use, and their purpose.
> > 
> > Signed-off-by: Ezequiel Garcia <ezequiel@collabora.com>
> > Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
> > Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
> 
> Reviewed-by: Helen Koike <helen.koike@collabora.com>
> 
> Thanks for working on this :)

And thank you for the reviews! :-)

-- 
Sakari Ailus

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH v5 11/13] media: v4l2-async: Discourage use of v4l2_async_notifier_add_subdev
  2021-02-02 13:56 ` [PATCH v5 11/13] media: v4l2-async: Discourage use of v4l2_async_notifier_add_subdev Sakari Ailus
@ 2021-02-06  8:15   ` Mauro Carvalho Chehab
  2021-02-08 10:32     ` Sakari Ailus
  0 siblings, 1 reply; 25+ messages in thread
From: Mauro Carvalho Chehab @ 2021-02-06  8:15 UTC (permalink / raw)
  To: Sakari Ailus
  Cc: linux-media, Hans Verkuil, kernel, Laurent Pinchart,
	Kieran Bingham, Jacopo Mondi, niklas.soderlund+renesas,
	Helen Koike, Dafna Hirschfeld, Hugues Fruchet, Nicolas Ferre,
	Yong Zhi, Sylwester Nawrocki, Maxime Ripard, Robert Foss,
	Philipp Zabel, Ezequiel Garcia

Em Tue,  2 Feb 2021 15:56:09 +0200
Sakari Ailus <sakari.ailus@linux.intel.com> escreveu:

> From: Ezequiel Garcia <ezequiel@collabora.com>
> 
> Most -if not all- use-cases are expected to be covered by one of:
> v4l2_async_notifier_add_fwnode_subdev,
> v4l2_async_notifier_add_fwnode_remote_subdev or
> v4l2_async_notifier_add_i2c_subdev.

Actually, all cases outside V4L2 core:

$ git grep v4l2_async_notifier_add_subdev
Documentation/driver-api/media/v4l2-subdev.rst:using the :c:func:`v4l2_async_notifier_add_subdev` call. This function
drivers/media/v4l2-core/v4l2-async.c:int v4l2_async_notifier_add_subdev(struct v4l2_async_notifier *notifier,
drivers/media/v4l2-core/v4l2-async.c:EXPORT_SYMBOL_GPL(v4l2_async_notifier_add_subdev);
drivers/media/v4l2-core/v4l2-async.c:   ret = v4l2_async_notifier_add_subdev(notifier, asd);
drivers/media/v4l2-core/v4l2-async.c:   ret = v4l2_async_notifier_add_subdev(notifier, asd);
drivers/media/v4l2-core/v4l2-fwnode.c:  ret = v4l2_async_notifier_add_subdev(notifier, asd);
include/media/v4l2-async.h: * before the first call to @v4l2_async_notifier_add_subdev.
include/media/v4l2-async.h: * v4l2_async_notifier_add_subdev - Add an async subdev to the
include/media/v4l2-async.h:int v4l2_async_notifier_add_subdev(struct v4l2_async_notifier *notifier,
include/media/v4l2-async.h: * @v4l2_async_notifier_add_subdev,


> 
> We'd like to discourage drivers from using v4l2_async_notifier_add_subdev,
> so rename it as __v4l2_async_notifier_add_subdev. This is
> typically a good hint for drivers to avoid using the function.

IMO, the best here would be to create a header file:

	drivers/media/v4l2-core/v4l2-async-priv.h

and move v4l2_async_notifier_add_subdev from include/media/v4l2-async.h.

This will warrant that only the V4L2 core would have access to it.
Also, it is a lot better than adding something like this:

> + * \warning: Drivers should avoid using this function and instead use one of:
> + * @v4l2_async_notifier_add_fwnode_subdev,
> + * @v4l2_async_notifier_add_fwnode_remote_subdev or
> + * @v4l2_async_notifier_add_i2c_subdev.
> + *


Please submit a followup patch.

-

On a separate but related note, The names of the async notifiers are
too big, causing lots of coding style warnings, like:

+       asd = v4l2_async_notifier_add_fwnode_remote_subdev(
+               &fmd->subdev_notifier, of_fwnode_handle(ep), sizeof(*asd));
...
+                       asd = v4l2_async_notifier_add_fwnode_remote_subdev(
+                               &isp->notifier, ep, sizeof(*isd));

Ending a line with an open parenthesis is not natural: you won't see
any good written English texts (or on any other natural language) that would
have a line ending with a '('.

While I understand that the name describes precisely what those 
functions, such non-intuitive usage of parenthesis makes the line
obfuscated, for no good reason.

Also, the entire meaning of the V4L2 async API is to allow subdevs
to be registered later. So, IMHO, the namespace for those 3
calls could be simplified to:

	v4l2_async_notifier_add_fwnode(),
	v4l2_async_notifier_add_fwnode_remote()
	v4l2_async_notifier_add_i2c().

Also, we should place at least the first argument afer the
parenthesis, even if this would violate the 80 columns
coding style rule[1]. 

So, the above examples would be written as:


        asd = v4l2_async_notifier_add_fwnode_remote(&fmd->subdev_notifier,
						    of_fwnode_handle(ep),
						    sizeof(*asd));

and:

                        asd = v4l2_async_notifier_add_fwnode_remote(&isp->notifier,
								    ep,
								    sizeof(*isd));

Which better matches the Kernel coding style, and it is way easier to
review, as the brain will see the parenthesis just like it would on
a natural language.

[1] The 80 columns warning is a "soft" coding style violation. It serves
as a reference that either the function code is becoming too complex with too
many loops, or that the function names are becoming too big. As it produces
lots of false positives, and people were breaking strings or finishing
lines with open parenthesis, this rule got relaxed, and checkpatch now
warns only (by default) if the line has more than 100 columns.


> 
> Signed-off-by: Ezequiel Garcia <ezequiel@collabora.com>
> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
> Reviewed-by: Helen Koike <helen.koike@collabora.com>
> Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
> ---
>  drivers/media/v4l2-core/v4l2-async.c  | 8 ++++----
>  drivers/media/v4l2-core/v4l2-fwnode.c | 2 +-
>  include/media/v4l2-async.h            | 9 +++++++--
>  3 files changed, 12 insertions(+), 7 deletions(-)
> 
> diff --git a/drivers/media/v4l2-core/v4l2-async.c b/drivers/media/v4l2-core/v4l2-async.c
> index ed603ae63cad..d848db962dc7 100644
> --- a/drivers/media/v4l2-core/v4l2-async.c
> +++ b/drivers/media/v4l2-core/v4l2-async.c
> @@ -611,7 +611,7 @@ void v4l2_async_notifier_cleanup(struct v4l2_async_notifier *notifier)
>  }
>  EXPORT_SYMBOL_GPL(v4l2_async_notifier_cleanup);
>  
> -int v4l2_async_notifier_add_subdev(struct v4l2_async_notifier *notifier,
> +int __v4l2_async_notifier_add_subdev(struct v4l2_async_notifier *notifier,
>  				   struct v4l2_async_subdev *asd)
>  {
>  	int ret;
> @@ -628,7 +628,7 @@ int v4l2_async_notifier_add_subdev(struct v4l2_async_notifier *notifier,
>  	mutex_unlock(&list_lock);
>  	return ret;
>  }
> -EXPORT_SYMBOL_GPL(v4l2_async_notifier_add_subdev);
> +EXPORT_SYMBOL_GPL(__v4l2_async_notifier_add_subdev);
>  
>  struct v4l2_async_subdev *
>  v4l2_async_notifier_add_fwnode_subdev(struct v4l2_async_notifier *notifier,
> @@ -645,7 +645,7 @@ v4l2_async_notifier_add_fwnode_subdev(struct v4l2_async_notifier *notifier,
>  	asd->match_type = V4L2_ASYNC_MATCH_FWNODE;
>  	asd->match.fwnode = fwnode_handle_get(fwnode);
>  
> -	ret = v4l2_async_notifier_add_subdev(notifier, asd);
> +	ret = __v4l2_async_notifier_add_subdev(notifier, asd);
>  	if (ret) {
>  		fwnode_handle_put(fwnode);
>  		kfree(asd);
> @@ -695,7 +695,7 @@ v4l2_async_notifier_add_i2c_subdev(struct v4l2_async_notifier *notifier,
>  	asd->match.i2c.adapter_id = adapter_id;
>  	asd->match.i2c.address = address;
>  
> -	ret = v4l2_async_notifier_add_subdev(notifier, asd);
> +	ret = __v4l2_async_notifier_add_subdev(notifier, asd);
>  	if (ret) {
>  		kfree(asd);
>  		return ERR_PTR(ret);
> diff --git a/drivers/media/v4l2-core/v4l2-fwnode.c b/drivers/media/v4l2-core/v4l2-fwnode.c
> index c1c2b3060532..63be16c8eb83 100644
> --- a/drivers/media/v4l2-core/v4l2-fwnode.c
> +++ b/drivers/media/v4l2-core/v4l2-fwnode.c
> @@ -822,7 +822,7 @@ v4l2_async_notifier_fwnode_parse_endpoint(struct device *dev,
>  	if (ret < 0)
>  		goto out_err;
>  
> -	ret = v4l2_async_notifier_add_subdev(notifier, asd);
> +	ret = __v4l2_async_notifier_add_subdev(notifier, asd);
>  	if (ret < 0) {
>  		/* not an error if asd already exists */
>  		if (ret == -EEXIST)
> diff --git a/include/media/v4l2-async.h b/include/media/v4l2-async.h
> index 8815e233677e..b113329582ff 100644
> --- a/include/media/v4l2-async.h
> +++ b/include/media/v4l2-async.h
> @@ -133,17 +133,22 @@ void v4l2_async_debug_init(struct dentry *debugfs_dir);
>  void v4l2_async_notifier_init(struct v4l2_async_notifier *notifier);
>  
>  /**
> - * v4l2_async_notifier_add_subdev - Add an async subdev to the
> + * __v4l2_async_notifier_add_subdev - Add an async subdev to the
>   *				notifier's master asd list.
>   *
>   * @notifier: pointer to &struct v4l2_async_notifier
>   * @asd: pointer to &struct v4l2_async_subdev
>   *
> + * \warning: Drivers should avoid using this function and instead use one of:
> + * @v4l2_async_notifier_add_fwnode_subdev,
> + * @v4l2_async_notifier_add_fwnode_remote_subdev or
> + * @v4l2_async_notifier_add_i2c_subdev.
> + *

The markups here are violating kernel-doc. Functions should be declared
as:

    * v4l2_async_notifier_add_fwnode_subdev(),
    * v4l2_async_notifier_add_fwnode_remote_subdev() or
    * v4l2_async_notifier_add_i2c_subdev().

Please address it on a followup patch.


>   * Call this function before registering a notifier to link the provided @asd to
>   * the notifiers master @asd_list. The @asd must be allocated with k*alloc() as
>   * it will be freed by the framework when the notifier is destroyed.
>   */
> -int v4l2_async_notifier_add_subdev(struct v4l2_async_notifier *notifier,
> +int __v4l2_async_notifier_add_subdev(struct v4l2_async_notifier *notifier,
>  				   struct v4l2_async_subdev *asd);
>  
>  /**



Thanks,
Mauro

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH v5 13/13] media: Clarify v4l2-async subdevice addition API
  2021-02-02 13:56 ` [PATCH v5 13/13] media: Clarify v4l2-async subdevice addition API Sakari Ailus
  2021-02-02 14:01   ` Helen Koike
  2021-02-02 14:25   ` [PATCH v5.1 " Sakari Ailus
@ 2021-02-06  8:29   ` Mauro Carvalho Chehab
  2021-02-08  8:35     ` Sakari Ailus
  2 siblings, 1 reply; 25+ messages in thread
From: Mauro Carvalho Chehab @ 2021-02-06  8:29 UTC (permalink / raw)
  To: Sakari Ailus
  Cc: linux-media, Hans Verkuil, kernel, Laurent Pinchart,
	Kieran Bingham, Jacopo Mondi, niklas.soderlund+renesas,
	Helen Koike, Dafna Hirschfeld, Hugues Fruchet, Nicolas Ferre,
	Yong Zhi, Sylwester Nawrocki, Maxime Ripard, Robert Foss,
	Philipp Zabel, Ezequiel Garcia

Em Tue,  2 Feb 2021 15:56:11 +0200
Sakari Ailus <sakari.ailus@linux.intel.com> escreveu:

> From: Ezequiel Garcia <ezequiel@collabora.com>
> 
> Now that most users of v4l2_async_notifier_add_subdev have been converted,
> let's fix the documentation so it's more clear how the v4l2-async API
> should be used.
> 
> Document functions that drivers should use, and their purpose.
> 
> Signed-off-by: Ezequiel Garcia <ezequiel@collabora.com>
> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
> Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
> ---
>  .../driver-api/media/v4l2-subdev.rst          | 48 +++++++++++++++----
>  include/media/v4l2-async.h                    | 15 ++++--
>  2 files changed, 50 insertions(+), 13 deletions(-)
> 
> diff --git a/Documentation/driver-api/media/v4l2-subdev.rst b/Documentation/driver-api/media/v4l2-subdev.rst
> index 0e82c77cf3e2..8b53da2f9c74 100644
> --- a/Documentation/driver-api/media/v4l2-subdev.rst
> +++ b/Documentation/driver-api/media/v4l2-subdev.rst
> @@ -197,15 +197,45 @@ unregister the notifier the driver has to call
>  takes two arguments: a pointer to struct :c:type:`v4l2_device` and a
>  pointer to struct :c:type:`v4l2_async_notifier`.
>  
> -Before registering the notifier, bridge drivers must do two things:
> -first, the notifier must be initialized using the
> -:c:func:`v4l2_async_notifier_init`. Second, bridge drivers can then
> -begin to form a list of subdevice descriptors that the bridge device
> -needs for its operation. Subdevice descriptors are added to the notifier
> -using the :c:func:`v4l2_async_notifier_add_subdev` call. This function
> -takes two arguments: a pointer to struct :c:type:`v4l2_async_notifier`,
> -and a pointer to the subdevice descripter, which is of type struct
> -:c:type:`v4l2_async_subdev`.
> +Before registering the notifier, bridge drivers must do two things: first, the
> +notifier must be initialized using the :c:func:`v4l2_async_notifier_init`.
> +Second, bridge drivers can then begin to form a list of subdevice descriptors
> +that the bridge device needs for its operation. Several functions are available
> +to add subdevice descriptors to a notifier, depending on the type of device and
> +the needs of the driver.
> +
> +:c:func:`v4l2_async_notifier_add_fwnode_remote_subdev` and
> +:c:func:`v4l2_async_notifier_add_i2c_subdev` are for bridge and ISP drivers for
> +registering their async sub-devices with the notifier.
> +
> +:c:func:`v4l2_async_register_subdev_sensor_common` is a helper function for
> +sensor drivers registering their own async sub-device, but it also registers a
> +notifier and further registers async sub-devices for lens and flash devices
> +found in firmware. The notifier for the sub-device is unregistered with the
> +async sub-device.
> +
> +These functions allocate an async sub-device descriptor which is of type struct
> +:c:type:`v4l2_async_subdev` embedded in a driver-specific struct. The &struct
> +:c:type:`v4l2_async_subdev` shall be the first member of this struct:


There's absolutely no need anymore to use:

	struct :c:type:`v4l2_async_subdev`

or
	:c:func:`v4l2_async_notifier_add_fwnode_remote_subdev`

In a matter of fact, this can even cause troubles with newer versions of
Sphinx, as, after version 3.0, structs should be declared as:

	:c:struct:`foo`

Our building system has gained a few years ago a Sphinx extension that
will automatically use the right markup, if all structs are declared
as:
	struct foo

and all functions as:

	bar()

So, the last two paragraphs could be simply:

	v4l2_async_register_subdev_sensor_common() is a helper function for
	sensor drivers registering their own async sub-device, but it also registers a
	notifier and further registers async sub-devices for lens and flash devices
	found in firmware. The notifier for the sub-device is unregistered with the
	async sub-device.

	These functions allocate an async sub-device descriptor which is of type
	struct v4l2_async_subdev embedded in a driver-specific struct. The 
	struct v4l2_async_subdev shall be the first member of this struct:

PS.: I guess the automarkup.py would accept having something like:

	very big line here with lots of words... struct
	foo

IMHO, for people reading the text files, it is a lot easier to keep
"struct foo" at the same line, like:

	very big line here with lots of words... 
	struct foo


> +
> +.. code-block:: c
> +
> +	struct my_async_subdev {
> +		struct v4l2_async_subdev asd;
> +		...
> +	};
> +
> +	struct my_async_subdev *my_asd;
> +	struct fwnode_handle *ep;
> +
> +	...
> +
> +	my_asd = v4l2_async_notifier_add_fwnode_remote_subdev(&notifier, ep,
> +							      struct my_async_subdev);
> +	fwnode_handle_put(ep);
> +
> +	if (IS_ERR(asd))
> +		return PTR_ERR(asd);
>  
>  The V4L2 core will then use these descriptors to match asynchronously
>  registered subdevices to them. If a match is detected the ``.bound()``
> diff --git a/include/media/v4l2-async.h b/include/media/v4l2-async.h
> index 192a11bdc4ad..6dac6cb6290f 100644
> --- a/include/media/v4l2-async.h
> +++ b/include/media/v4l2-async.h
> @@ -128,7 +128,12 @@ void v4l2_async_debug_init(struct dentry *debugfs_dir);
>   * @notifier: pointer to &struct v4l2_async_notifier
>   *
>   * This function initializes the notifier @asd_list. It must be called
> - * before the first call to @v4l2_async_notifier_add_subdev.
> + * before adding a subdevice to a notifier, using one of:
> + * @v4l2_async_notifier_add_fwnode_remote_subdev,
> + * @v4l2_async_notifier_add_fwnode_subdev,
> + * @v4l2_async_notifier_add_i2c_subdev,
> + * @v4l2_async_notifier_add_subdev or
> + * @v4l2_async_notifier_parse_fwnode_endpoints.

The markups here are wrong:

'@foo' is to be used for literal blocks. It won't produce
any cross-references. The right way to describe functions is to
write it as:
	foo()

>   */
>  void v4l2_async_notifier_init(struct v4l2_async_notifier *notifier);
>  
> @@ -262,9 +267,11 @@ void v4l2_async_notifier_unregister(struct v4l2_async_notifier *notifier);
>   * 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_add_subdev,
> - * @v4l2_async_notifier_parse_fwnode_endpoints or
> - * @v4l2_fwnode_reference_parse_sensor_common.
> + * @v4l2_async_notifier_add_fwnode_remote_subdev,
> + * @v4l2_async_notifier_add_fwnode_subdev,
> + * @v4l2_async_notifier_add_i2c_subdev,
> + * @v4l2_async_notifier_add_subdev or
> + * @v4l2_async_notifier_parse_fwnode_endpoints.
>   *
>   * 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

Please send a followup patch.

Thanks,
Mauro

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH v5 13/13] media: Clarify v4l2-async subdevice addition API
  2021-02-06  8:29   ` [PATCH v5 " Mauro Carvalho Chehab
@ 2021-02-08  8:35     ` Sakari Ailus
  0 siblings, 0 replies; 25+ messages in thread
From: Sakari Ailus @ 2021-02-08  8:35 UTC (permalink / raw)
  To: Mauro Carvalho Chehab
  Cc: linux-media, Hans Verkuil, kernel, Laurent Pinchart,
	Kieran Bingham, Jacopo Mondi, niklas.soderlund+renesas,
	Helen Koike, Dafna Hirschfeld, Hugues Fruchet, Nicolas Ferre,
	Yong Zhi, Sylwester Nawrocki, Maxime Ripard, Robert Foss,
	Philipp Zabel, Ezequiel Garcia

Hi Mauro,

On Sat, Feb 06, 2021 at 09:29:54AM +0100, Mauro Carvalho Chehab wrote:
> Please send a followup patch.

Sure.

-- 
Sakari Ailus

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH v5 11/13] media: v4l2-async: Discourage use of v4l2_async_notifier_add_subdev
  2021-02-06  8:15   ` Mauro Carvalho Chehab
@ 2021-02-08 10:32     ` Sakari Ailus
  2021-02-08 12:54       ` Mauro Carvalho Chehab
  0 siblings, 1 reply; 25+ messages in thread
From: Sakari Ailus @ 2021-02-08 10:32 UTC (permalink / raw)
  To: Mauro Carvalho Chehab
  Cc: linux-media, Hans Verkuil, kernel, Laurent Pinchart,
	Kieran Bingham, Jacopo Mondi, niklas.soderlund+renesas,
	Helen Koike, Dafna Hirschfeld, Hugues Fruchet, Nicolas Ferre,
	Yong Zhi, Sylwester Nawrocki, Maxime Ripard, Robert Foss,
	Philipp Zabel, Ezequiel Garcia

Hi Mauro,

Thanks for the review.

On Sat, Feb 06, 2021 at 09:15:46AM +0100, Mauro Carvalho Chehab wrote:
> Em Tue,  2 Feb 2021 15:56:09 +0200
> Sakari Ailus <sakari.ailus@linux.intel.com> escreveu:
> 
> > From: Ezequiel Garcia <ezequiel@collabora.com>
> > 
> > Most -if not all- use-cases are expected to be covered by one of:
> > v4l2_async_notifier_add_fwnode_subdev,
> > v4l2_async_notifier_add_fwnode_remote_subdev or
> > v4l2_async_notifier_add_i2c_subdev.
> 
> Actually, all cases outside V4L2 core:
> 
> $ git grep v4l2_async_notifier_add_subdev
> Documentation/driver-api/media/v4l2-subdev.rst:using the :c:func:`v4l2_async_notifier_add_subdev` call. This function
> drivers/media/v4l2-core/v4l2-async.c:int v4l2_async_notifier_add_subdev(struct v4l2_async_notifier *notifier,
> drivers/media/v4l2-core/v4l2-async.c:EXPORT_SYMBOL_GPL(v4l2_async_notifier_add_subdev);
> drivers/media/v4l2-core/v4l2-async.c:   ret = v4l2_async_notifier_add_subdev(notifier, asd);
> drivers/media/v4l2-core/v4l2-async.c:   ret = v4l2_async_notifier_add_subdev(notifier, asd);
> drivers/media/v4l2-core/v4l2-fwnode.c:  ret = v4l2_async_notifier_add_subdev(notifier, asd);
> include/media/v4l2-async.h: * before the first call to @v4l2_async_notifier_add_subdev.
> include/media/v4l2-async.h: * v4l2_async_notifier_add_subdev - Add an async subdev to the
> include/media/v4l2-async.h:int v4l2_async_notifier_add_subdev(struct v4l2_async_notifier *notifier,
> include/media/v4l2-async.h: * @v4l2_async_notifier_add_subdev,
> 
> 
> > 
> > We'd like to discourage drivers from using v4l2_async_notifier_add_subdev,
> > so rename it as __v4l2_async_notifier_add_subdev. This is
> > typically a good hint for drivers to avoid using the function.
> 
> IMO, the best here would be to create a header file:
> 
> 	drivers/media/v4l2-core/v4l2-async-priv.h
> 
> and move v4l2_async_notifier_add_subdev from include/media/v4l2-async.h.
> 
> This will warrant that only the V4L2 core would have access to it.
> Also, it is a lot better than adding something like this:

It'd be the first header in the directory. I suppose there are other
functions that could have the prototype there.

I'll still see if there could be other options for this.

The topic of split into modules of v4l2-async and v4l2-fwnode was also
discussed recently, and it's obviously related to this. The two are
virtually always used together and so would make sense to be in the same
module. In practice this would mean moving v4l2-async out of videodev2. The
module wouldn't be large but the vast majority of regular laptop and
desktop PC users are having this in memory needlessly.

> 
> > + * \warning: Drivers should avoid using this function and instead use one of:
> > + * @v4l2_async_notifier_add_fwnode_subdev,
> > + * @v4l2_async_notifier_add_fwnode_remote_subdev or
> > + * @v4l2_async_notifier_add_i2c_subdev.
> > + *
> 
> 
> Please submit a followup patch.

Yes.

> 
> -
> 
> On a separate but related note, The names of the async notifiers are
> too big, causing lots of coding style warnings, like:
> 
> +       asd = v4l2_async_notifier_add_fwnode_remote_subdev(
> +               &fmd->subdev_notifier, of_fwnode_handle(ep), sizeof(*asd));
> ...
> +                       asd = v4l2_async_notifier_add_fwnode_remote_subdev(
> +                               &isp->notifier, ep, sizeof(*isd));

We started with lots of variants of similar functions over time, so I
preferred to keep the names descriptive. Now that we've settled to a small
number of them, it's also worth seeing whether there could be room for
shorter but still descriptive names without allowing for such variance we
no longer need.

> 
> Ending a line with an open parenthesis is not natural: you won't see
> any good written English texts (or on any other natural language) that would
> have a line ending with a '('.

This is C, not English, and I'm sure we could have a long debate on the
topic. :-) But maybe we don't need to.

> 
> While I understand that the name describes precisely what those 
> functions, such non-intuitive usage of parenthesis makes the line
> obfuscated, for no good reason.
> 
> Also, the entire meaning of the V4L2 async API is to allow subdevs
> to be registered later. So, IMHO, the namespace for those 3
> calls could be simplified to:
> 
> 	v4l2_async_notifier_add_fwnode(),
> 	v4l2_async_notifier_add_fwnode_remote()
> 	v4l2_async_notifier_add_i2c().

Yes, I had actually the same in mind. Seems reasonable.

> 
> Also, we should place at least the first argument afer the
> parenthesis, even if this would violate the 80 columns
> coding style rule[1]. 
> 
> So, the above examples would be written as:
> 
> 
>         asd = v4l2_async_notifier_add_fwnode_remote(&fmd->subdev_notifier,
> 						    of_fwnode_handle(ep),
> 						    sizeof(*asd));
> 
> and:
> 
>                         asd = v4l2_async_notifier_add_fwnode_remote(&isp->notifier,
> 								    ep,
> 								    sizeof(*isd));
> 
> Which better matches the Kernel coding style, and it is way easier to
> review, as the brain will see the parenthesis just like it would on
> a natural language.
> 
> [1] The 80 columns warning is a "soft" coding style violation. It serves
> as a reference that either the function code is becoming too complex with too
> many loops, or that the function names are becoming too big. As it produces
> lots of false positives, and people were breaking strings or finishing
> lines with open parenthesis, this rule got relaxed, and checkpatch now
> warns only (by default) if the line has more than 100 columns.

The coding style refers to it as the "preferred limit", indeed. But there
are conditions how exceeding that is allowed.

Note that aligning the function arguments on the following lines to right
of the opening parenthesis is also referred to as a "very commonly used
style", i.e. there is no suggestion it is a requirement. That is certainly
my preference as well, but I guess it's the priority of these preferences
that we'd be discussing.

Let's see how much making the names shorter helps.

> 
> 
> > 
> > Signed-off-by: Ezequiel Garcia <ezequiel@collabora.com>
> > Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
> > Reviewed-by: Helen Koike <helen.koike@collabora.com>
> > Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
> > ---
> >  drivers/media/v4l2-core/v4l2-async.c  | 8 ++++----
> >  drivers/media/v4l2-core/v4l2-fwnode.c | 2 +-
> >  include/media/v4l2-async.h            | 9 +++++++--
> >  3 files changed, 12 insertions(+), 7 deletions(-)
> > 
> > diff --git a/drivers/media/v4l2-core/v4l2-async.c b/drivers/media/v4l2-core/v4l2-async.c
> > index ed603ae63cad..d848db962dc7 100644
> > --- a/drivers/media/v4l2-core/v4l2-async.c
> > +++ b/drivers/media/v4l2-core/v4l2-async.c
> > @@ -611,7 +611,7 @@ void v4l2_async_notifier_cleanup(struct v4l2_async_notifier *notifier)
> >  }
> >  EXPORT_SYMBOL_GPL(v4l2_async_notifier_cleanup);
> >  
> > -int v4l2_async_notifier_add_subdev(struct v4l2_async_notifier *notifier,
> > +int __v4l2_async_notifier_add_subdev(struct v4l2_async_notifier *notifier,
> >  				   struct v4l2_async_subdev *asd)
> >  {
> >  	int ret;
> > @@ -628,7 +628,7 @@ int v4l2_async_notifier_add_subdev(struct v4l2_async_notifier *notifier,
> >  	mutex_unlock(&list_lock);
> >  	return ret;
> >  }
> > -EXPORT_SYMBOL_GPL(v4l2_async_notifier_add_subdev);
> > +EXPORT_SYMBOL_GPL(__v4l2_async_notifier_add_subdev);
> >  
> >  struct v4l2_async_subdev *
> >  v4l2_async_notifier_add_fwnode_subdev(struct v4l2_async_notifier *notifier,
> > @@ -645,7 +645,7 @@ v4l2_async_notifier_add_fwnode_subdev(struct v4l2_async_notifier *notifier,
> >  	asd->match_type = V4L2_ASYNC_MATCH_FWNODE;
> >  	asd->match.fwnode = fwnode_handle_get(fwnode);
> >  
> > -	ret = v4l2_async_notifier_add_subdev(notifier, asd);
> > +	ret = __v4l2_async_notifier_add_subdev(notifier, asd);
> >  	if (ret) {
> >  		fwnode_handle_put(fwnode);
> >  		kfree(asd);
> > @@ -695,7 +695,7 @@ v4l2_async_notifier_add_i2c_subdev(struct v4l2_async_notifier *notifier,
> >  	asd->match.i2c.adapter_id = adapter_id;
> >  	asd->match.i2c.address = address;
> >  
> > -	ret = v4l2_async_notifier_add_subdev(notifier, asd);
> > +	ret = __v4l2_async_notifier_add_subdev(notifier, asd);
> >  	if (ret) {
> >  		kfree(asd);
> >  		return ERR_PTR(ret);
> > diff --git a/drivers/media/v4l2-core/v4l2-fwnode.c b/drivers/media/v4l2-core/v4l2-fwnode.c
> > index c1c2b3060532..63be16c8eb83 100644
> > --- a/drivers/media/v4l2-core/v4l2-fwnode.c
> > +++ b/drivers/media/v4l2-core/v4l2-fwnode.c
> > @@ -822,7 +822,7 @@ v4l2_async_notifier_fwnode_parse_endpoint(struct device *dev,
> >  	if (ret < 0)
> >  		goto out_err;
> >  
> > -	ret = v4l2_async_notifier_add_subdev(notifier, asd);
> > +	ret = __v4l2_async_notifier_add_subdev(notifier, asd);
> >  	if (ret < 0) {
> >  		/* not an error if asd already exists */
> >  		if (ret == -EEXIST)
> > diff --git a/include/media/v4l2-async.h b/include/media/v4l2-async.h
> > index 8815e233677e..b113329582ff 100644
> > --- a/include/media/v4l2-async.h
> > +++ b/include/media/v4l2-async.h
> > @@ -133,17 +133,22 @@ void v4l2_async_debug_init(struct dentry *debugfs_dir);
> >  void v4l2_async_notifier_init(struct v4l2_async_notifier *notifier);
> >  
> >  /**
> > - * v4l2_async_notifier_add_subdev - Add an async subdev to the
> > + * __v4l2_async_notifier_add_subdev - Add an async subdev to the
> >   *				notifier's master asd list.
> >   *
> >   * @notifier: pointer to &struct v4l2_async_notifier
> >   * @asd: pointer to &struct v4l2_async_subdev
> >   *
> > + * \warning: Drivers should avoid using this function and instead use one of:
> > + * @v4l2_async_notifier_add_fwnode_subdev,
> > + * @v4l2_async_notifier_add_fwnode_remote_subdev or
> > + * @v4l2_async_notifier_add_i2c_subdev.
> > + *
> 
> The markups here are violating kernel-doc. Functions should be declared
> as:
> 
>     * v4l2_async_notifier_add_fwnode_subdev(),
>     * v4l2_async_notifier_add_fwnode_remote_subdev() or
>     * v4l2_async_notifier_add_i2c_subdev().
> 
> Please address it on a followup patch.

Sure.

-- 
Kind regards,

Sakari Ailus

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH v5 11/13] media: v4l2-async: Discourage use of v4l2_async_notifier_add_subdev
  2021-02-08 10:32     ` Sakari Ailus
@ 2021-02-08 12:54       ` Mauro Carvalho Chehab
  2021-02-08 14:40         ` Ezequiel Garcia
  0 siblings, 1 reply; 25+ messages in thread
From: Mauro Carvalho Chehab @ 2021-02-08 12:54 UTC (permalink / raw)
  To: Sakari Ailus
  Cc: linux-media, Hans Verkuil, kernel, Laurent Pinchart,
	Kieran Bingham, Jacopo Mondi, niklas.soderlund+renesas,
	Helen Koike, Dafna Hirschfeld, Hugues Fruchet, Nicolas Ferre,
	Yong Zhi, Sylwester Nawrocki, Maxime Ripard, Robert Foss,
	Philipp Zabel, Ezequiel Garcia

Em Mon, 8 Feb 2021 12:32:44 +0200
Sakari Ailus <sakari.ailus@linux.intel.com> escreveu:

> Hi Mauro,
> 
> Thanks for the review.
> 
> On Sat, Feb 06, 2021 at 09:15:46AM +0100, Mauro Carvalho Chehab wrote:
> > Em Tue,  2 Feb 2021 15:56:09 +0200
> > Sakari Ailus <sakari.ailus@linux.intel.com> escreveu:
> >   
> > > From: Ezequiel Garcia <ezequiel@collabora.com>
> > > 
> > > Most -if not all- use-cases are expected to be covered by one of:
> > > v4l2_async_notifier_add_fwnode_subdev,
> > > v4l2_async_notifier_add_fwnode_remote_subdev or
> > > v4l2_async_notifier_add_i2c_subdev.  
> > 
> > Actually, all cases outside V4L2 core:
> > 
> > $ git grep v4l2_async_notifier_add_subdev
> > Documentation/driver-api/media/v4l2-subdev.rst:using the :c:func:`v4l2_async_notifier_add_subdev` call. This function
> > drivers/media/v4l2-core/v4l2-async.c:int v4l2_async_notifier_add_subdev(struct v4l2_async_notifier *notifier,
> > drivers/media/v4l2-core/v4l2-async.c:EXPORT_SYMBOL_GPL(v4l2_async_notifier_add_subdev);
> > drivers/media/v4l2-core/v4l2-async.c:   ret = v4l2_async_notifier_add_subdev(notifier, asd);
> > drivers/media/v4l2-core/v4l2-async.c:   ret = v4l2_async_notifier_add_subdev(notifier, asd);
> > drivers/media/v4l2-core/v4l2-fwnode.c:  ret = v4l2_async_notifier_add_subdev(notifier, asd);
> > include/media/v4l2-async.h: * before the first call to @v4l2_async_notifier_add_subdev.
> > include/media/v4l2-async.h: * v4l2_async_notifier_add_subdev - Add an async subdev to the
> > include/media/v4l2-async.h:int v4l2_async_notifier_add_subdev(struct v4l2_async_notifier *notifier,
> > include/media/v4l2-async.h: * @v4l2_async_notifier_add_subdev,
> > 
> >   
> > > 
> > > We'd like to discourage drivers from using v4l2_async_notifier_add_subdev,
> > > so rename it as __v4l2_async_notifier_add_subdev. This is
> > > typically a good hint for drivers to avoid using the function.  
> > 
> > IMO, the best here would be to create a header file:
> > 
> > 	drivers/media/v4l2-core/v4l2-async-priv.h
> > 
> > and move v4l2_async_notifier_add_subdev from include/media/v4l2-async.h.
> > 
> > This will warrant that only the V4L2 core would have access to it.
> > Also, it is a lot better than adding something like this:  
> 
> It'd be the first header in the directory. I suppose there are other
> functions that could have the prototype there.
> 
> I'll still see if there could be other options for this.
> 
> The topic of split into modules of v4l2-async and v4l2-fwnode was also
> discussed recently, and it's obviously related to this. The two are
> virtually always used together and so would make sense to be in the same
> module. In practice this would mean moving v4l2-async out of videodev2. The
> module wouldn't be large but the vast majority of regular laptop and
> desktop PC users are having this in memory needlessly.

IMO, splitting kAPI headers from v4l-core internal usage is a good
idea for the things that should be used only inside the core.

The RC core has one such header:

	drivers/media/rc/rc-core-priv.h

Several DVB frontend and tuner drivers also have things like that.


> > On a separate but related note, The names of the async notifiers are
> > too big, causing lots of coding style warnings, like:
> > 
> > +       asd = v4l2_async_notifier_add_fwnode_remote_subdev(
> > +               &fmd->subdev_notifier, of_fwnode_handle(ep), sizeof(*asd));
> > ...
> > +                       asd = v4l2_async_notifier_add_fwnode_remote_subdev(
> > +                               &isp->notifier, ep, sizeof(*isd));  
> 
> We started with lots of variants of similar functions over time, so I
> preferred to keep the names descriptive. Now that we've settled to a small
> number of them, it's also worth seeing whether there could be room for
> shorter but still descriptive names without allowing for such variance we
> no longer need.

Yeah, now that there are just 3 variants, those could be renamed to
a shorter yet meaningful names.

> > Ending a line with an open parenthesis is not natural: you won't see
> > any good written English texts (or on any other natural language) that would
> > have a line ending with a '('.  
> 
> This is C, not English, and I'm sure we could have a long debate on the
> topic. :-) But maybe we don't need to.

Yes, but the brains that read C source code are the same that were
trained since childhood to read English (and/or other natural languages).

That's probably why computer languages like MUMPS, where a program would
look like:

	GREPTHIS()
	       N S,N,T,I,K,Q S I="K",S="11",K="l1",Q="R",T="K"
	       I I=T D T
	       Q:$Q Q Q
	T  I I,S&K S S=S+K Q

	f i=0:5:25 w i," "

got deprecated... It is very hard for a human brain to understand
that. It is also a maintenance nightmare, as even the original
programmer will have a bad time to understand what it was written
there.

The main purpose of the coding style is to make the source code to be
easier to be understood.

That's basically why the 80-columns limit is a "soft limit": it is not
the size of a line that makes a program harder to be understood,
but, instead, the excess of loops on it.

> > 
> > While I understand that the name describes precisely what those 
> > functions, such non-intuitive usage of parenthesis makes the line
> > obfuscated, for no good reason.
> > 
> > Also, the entire meaning of the V4L2 async API is to allow subdevs
> > to be registered later. So, IMHO, the namespace for those 3
> > calls could be simplified to:
> > 
> > 	v4l2_async_notifier_add_fwnode(),
> > 	v4l2_async_notifier_add_fwnode_remote()
> > 	v4l2_async_notifier_add_i2c().  
> 
> Yes, I had actually the same in mind. Seems reasonable.

Great!
 
> > Also, we should place at least the first argument afer the
> > parenthesis, even if this would violate the 80 columns
> > coding style rule[1]. 
> > 
> > So, the above examples would be written as:
> > 
> > 
> >         asd = v4l2_async_notifier_add_fwnode_remote(&fmd->subdev_notifier,
> > 						    of_fwnode_handle(ep),
> > 						    sizeof(*asd));
> > 
> > and:
> > 
> >                         asd = v4l2_async_notifier_add_fwnode_remote(&isp->notifier,
> > 								    ep,
> > 								    sizeof(*isd));
> > 
> > Which better matches the Kernel coding style, and it is way easier to
> > review, as the brain will see the parenthesis just like it would on
> > a natural language.
> > 
> > [1] The 80 columns warning is a "soft" coding style violation. It serves
> > as a reference that either the function code is becoming too complex with too
> > many loops, or that the function names are becoming too big. As it produces
> > lots of false positives, and people were breaking strings or finishing
> > lines with open parenthesis, this rule got relaxed, and checkpatch now
> > warns only (by default) if the line has more than 100 columns.  
> 
> The coding style refers to it as the "preferred limit", indeed. But there
> are conditions how exceeding that is allowed.

Yep, but, while not explicitly written there, "preferred" implies that
people should use a good sense on that. See the first paragraph:

	2) Breaking long lines and strings
	----------------------------------

	Coding style is all about readability and maintainability using commonly
	available tools.

	The preferred limit on the length of a single line is 80 columns.

	Statements longer than 80 columns should be broken into sensible chunks,
	unless exceeding 80 columns significantly increases readability and does
	not hide information.

The goal is to improve "readability". When you place a parenthesis on a
non-natural order, you're not improving readability. It's quite 
the opposite.

I've seen enough badly-written source lines on media because in the past,
the 80-columns limits were enforced (and because tools like indent that
were widely used in the past are very bad when applying line size limits).

> Note that aligning the function arguments on the following lines to right
> of the opening parenthesis is also referred to as a "very commonly used
> style", i.e. there is no suggestion it is a requirement. That is certainly
> my preference as well, but I guess it's the priority of these preferences
> that we'd be discussing.

Yeah, this was not enforced for the same reason: sometimes, people ended
doing crazy things like:

	dvb->i2c_client_demod = dvb_module_probe("lgdt3306a", NULL,
						 &dev->
						  i2c_adap[dev->
						           def_i2c_bus],
						 addr, 
						 &lgdt3306a_config);

in order to follow this kind of requirement.

(this is not a real example, but tools like indent used to generate
things like the above)

FYI, the above code, is inside em28xx-dvb.c, as:

	dvb->i2c_client_demod = dvb_module_probe("lgdt3306a", NULL,
						 &dev->i2c_adap[dev->def_i2c_bus],
						 addr, &lgdt3306a_config);


This violates the 80 column soft limit, but its readibility is a way better
than:

	dvb->i2c_client_demod = dvb_module_probe("lgdt3306a", NULL,
					 &dev->i2c_adap[dev->def_i2c_bus],
					 addr, &lgdt3306a_config);


(which would be an alternative that it is less readable than
the current code).

> Let's see how much making the names shorter helps.

I suspect it will solve most issues, if not all.

Thanks,
Mauro

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH v5 11/13] media: v4l2-async: Discourage use of v4l2_async_notifier_add_subdev
  2021-02-08 12:54       ` Mauro Carvalho Chehab
@ 2021-02-08 14:40         ` Ezequiel Garcia
  0 siblings, 0 replies; 25+ messages in thread
From: Ezequiel Garcia @ 2021-02-08 14:40 UTC (permalink / raw)
  To: Mauro Carvalho Chehab, Sakari Ailus
  Cc: linux-media, Hans Verkuil, kernel, Laurent Pinchart,
	Kieran Bingham, Jacopo Mondi, niklas.soderlund+renesas,
	Helen Koike, Dafna Hirschfeld, Hugues Fruchet, Nicolas Ferre,
	Yong Zhi, Sylwester Nawrocki, Maxime Ripard, Robert Foss,
	Philipp Zabel

Hi Mauro,

On Mon, 2021-02-08 at 13:54 +0100, Mauro Carvalho Chehab wrote:
> Em Mon, 8 Feb 2021 12:32:44 +0200
> Sakari Ailus <sakari.ailus@linux.intel.com> escreveu:
> 
> > Hi Mauro,
> > 
> > Thanks for the review.
> > 
> > On Sat, Feb 06, 2021 at 09:15:46AM +0100, Mauro Carvalho Chehab wrote:
> > > Em Tue,  2 Feb 2021 15:56:09 +0200
> > > Sakari Ailus <sakari.ailus@linux.intel.com> escreveu:
> > >   
> > > > From: Ezequiel Garcia <ezequiel@collabora.com>
> > > > 
> > > > Most -if not all- use-cases are expected to be covered by one of:
> > > > v4l2_async_notifier_add_fwnode_subdev,
> > > > v4l2_async_notifier_add_fwnode_remote_subdev or
> > > > v4l2_async_notifier_add_i2c_subdev.  
> > > 
> > > Actually, all cases outside V4L2 core:
> > > 
> > > $ git grep v4l2_async_notifier_add_subdev
> > > Documentation/driver-api/media/v4l2-subdev.rst:using the :c:func:`v4l2_async_notifier_add_subdev` call. This function
> > > drivers/media/v4l2-core/v4l2-async.c:int v4l2_async_notifier_add_subdev(struct v4l2_async_notifier *notifier,
> > > drivers/media/v4l2-core/v4l2-async.c:EXPORT_SYMBOL_GPL(v4l2_async_notifier_add_subdev);
> > > drivers/media/v4l2-core/v4l2-async.c:   ret = v4l2_async_notifier_add_subdev(notifier, asd);
> > > drivers/media/v4l2-core/v4l2-async.c:   ret = v4l2_async_notifier_add_subdev(notifier, asd);
> > > drivers/media/v4l2-core/v4l2-fwnode.c:  ret = v4l2_async_notifier_add_subdev(notifier, asd);
> > > include/media/v4l2-async.h: * before the first call to @v4l2_async_notifier_add_subdev.
> > > include/media/v4l2-async.h: * v4l2_async_notifier_add_subdev - Add an async subdev to the
> > > include/media/v4l2-async.h:int v4l2_async_notifier_add_subdev(struct v4l2_async_notifier *notifier,
> > > include/media/v4l2-async.h: * @v4l2_async_notifier_add_subdev,
> > > 
> > >   
> > > > 
> > > > We'd like to discourage drivers from using v4l2_async_notifier_add_subdev,
> > > > so rename it as __v4l2_async_notifier_add_subdev. This is
> > > > typically a good hint for drivers to avoid using the function.  
> > > 
> > > IMO, the best here would be to create a header file:
> > > 
> > >         drivers/media/v4l2-core/v4l2-async-priv.h
> > > 
> > > and move v4l2_async_notifier_add_subdev from include/media/v4l2-async.h.
> > > 
> > > This will warrant that only the V4L2 core would have access to it.
> > > Also, it is a lot better than adding something like this:  
> > 
> > It'd be the first header in the directory. I suppose there are other
> > functions that could have the prototype there.
> > 
> > I'll still see if there could be other options for this.
> > 
> > The topic of split into modules of v4l2-async and v4l2-fwnode was also
> > discussed recently, and it's obviously related to this. The two are
> > virtually always used together and so would make sense to be in the same
> > module. In practice this would mean moving v4l2-async out of videodev2. The
> > module wouldn't be large but the vast majority of regular laptop and
> > desktop PC users are having this in memory needlessly.
> 
> IMO, splitting kAPI headers from v4l-core internal usage is a good
> idea for the things that should be used only inside the core.
> 
> The RC core has one such header:
> 
>         drivers/media/rc/rc-core-priv.h
> 
> Several DVB frontend and tuner drivers also have things like that.
> 

This solution looks like the way to go. Thanks for bringing it up.

Specifically for v4l2-async, we were considering reorganizing the
code, perhaps removing the need for a private/core API.
We'll see how that goes.

Thanks,
Ezequiel


^ permalink raw reply	[flat|nested] 25+ messages in thread

end of thread, other threads:[~2021-02-08 14:41 UTC | newest]

Thread overview: 25+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-02-02 13:55 [PATCH v5 00/13] V4L2 Async notifier API cleanup Sakari Ailus
2021-02-02 13:55 ` [PATCH v5 01/13] media: v4l2-async: Clean v4l2_async_notifier_add_fwnode_remote_subdev Sakari Ailus
2021-02-02 13:56 ` [PATCH v5 02/13] media: atmel: Use v4l2_async_notifier_add_fwnode_remote_subdev Sakari Ailus
2021-02-02 13:56 ` [PATCH v5 03/13] media: stm32: " Sakari Ailus
2021-02-02 13:56 ` [PATCH v5 04/13] media: exynos4-is: " Sakari Ailus
2021-02-02 13:56 ` [PATCH v5 05/13] media: st-mipid02: " Sakari Ailus
2021-02-02 13:56 ` [PATCH v5 06/13] media: cadence: " Sakari Ailus
2021-02-02 13:56 ` [PATCH v5 07/13] media: marvell-ccic: Use v4l2_async_notifier_add_*_subdev Sakari Ailus
2021-02-02 13:56 ` [PATCH v5 08/13] media: renesas-ceu: " Sakari Ailus
2021-02-02 13:56 ` [PATCH v5 09/13] media: pxa-camera: " Sakari Ailus
2021-02-02 13:56 ` [PATCH v5 10/13] media: davinci: vpif_display: Remove unused v4l2-async code Sakari Ailus
2021-02-02 13:56 ` [PATCH v5 11/13] media: v4l2-async: Discourage use of v4l2_async_notifier_add_subdev Sakari Ailus
2021-02-06  8:15   ` Mauro Carvalho Chehab
2021-02-08 10:32     ` Sakari Ailus
2021-02-08 12:54       ` Mauro Carvalho Chehab
2021-02-08 14:40         ` Ezequiel Garcia
2021-02-02 13:56 ` [PATCH v5 12/13] media: v4l2-async: Improve v4l2_async_notifier_add_*_subdev() API Sakari Ailus
2021-02-02 13:56 ` [PATCH v5 13/13] media: Clarify v4l2-async subdevice addition API Sakari Ailus
2021-02-02 14:01   ` Helen Koike
2021-02-02 14:19     ` Sakari Ailus
2021-02-02 14:25   ` [PATCH v5.1 " Sakari Ailus
2021-02-02 15:23     ` Helen Koike
2021-02-02 18:15       ` Sakari Ailus
2021-02-06  8:29   ` [PATCH v5 " Mauro Carvalho Chehab
2021-02-08  8:35     ` Sakari Ailus

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.