Linux Media Controller development
 help / color / mirror / Atom feed
* [PATCH v3 00/29] Rework frame descriptors
@ 2026-08-24 12:14 Sakari Ailus
  2026-08-24 12:14 ` [PATCH v3 01/29] media: v4l2-common: Add helper function media_bus_fmt_to_csi2_(bpp|dt)() Sakari Ailus
                   ` (29 more replies)
  0 siblings, 30 replies; 67+ messages in thread
From: Sakari Ailus @ 2026-08-24 12:14 UTC (permalink / raw)
  To: linux-media
  Cc: laurent.pinchart, Dave Stevenson, Jacopo Mondi, Tomi Valkeinen,
	Jai Luthra, Mehdi Djait, Mattijs Korpershoek

Hi folks,

This smallish set makes frame descriptors dynamically allocated and
implements a single-entry frame descriptor based on the device's format,
using a new helper called v4l2_subdev_get_frame_desc(). All drivers that
do not obtain their frame descriptor from upstream are converted. The
helper also obtains a frame descriptor for the desired type (parallel or
CSI-2) and checks there's at least one entry there. These checks are
removed from drivers that currently perform them. (Some drivers also check
there's exactly a single frame descriptor entry but I think in most cases
this check could be loosened. That could be done after this set.)

More formats can be added to df-to-mbus conversion as needed. These are
meant to be initial formats that are enough for typical raw sensors (and
one RGB format, too).

In the long run this information should probably reside in sub-device
state. This set however avoids having all receiver drivers to work with
sub-device drivers (~ 100 of such exist) that have a single stream and so
do not implement get_frame_desc() op.

since v2:

- Introduce v4l2_subdev_get_frame_desc_passthrough_csi2() and
  v4l2_subdev_get_frame_desc_passthrough_dvp(), which both set the
  bus_type field. Use v4l2_subdev_get_frame_desc_passthrough_csi2() in
  ds90ub913, ds90ub953, imx8-isi, rzg2l-cru and dw-mipi-csi2rx drivers.

- Remove the non-frame descriptor support upstream compatibility code in
  the unicam driver and handle errors in unicam_start_rx().

- Convert cdns-csi2rx, imx8-isi-pipe, rp1-cfe, j721e-csi2rx and ti-cal
  drivers to use v4l2_subdev_get_frame_desc().

- Add bits-per-pixel values to metadata mbus format info.

- Also allocate the streams in __v4l2_subdev_get_frame_desc_passthrough()
  if the pre-allocated array isn't large enough.

- Declare subdev_fmt in v4l2_subdev_get_frame_desc() where it is used.

- Document the get_frame_desc() op better in v4l2-subdev.h.

- Move the allocation of the frame descriptors if more than
  V4L2_FRAME_DESC_ENTRY_PREALLOC to the callee -- was in
  call_get_frame_desc() wrapper.

since v1:

- Take Frank's patch adding media bus format to dt / bpp conversion.
  Always return -EINVAL on error.

- Rework sub-device framework patch split to make the patches more
  reviewable.

- In call_get_frame_desc(), always set fd->entry to fd->entry_mem and
  fd->len_entries. Also use memset_after().

- Check for num_entries in call_get_frame_desc() first and thus remove the
  redundant else case.

- Check for validity of the returned frame descriptor type in
  call_get_frame_desc().

- Merge the patches adding v4l2_subdev_get_frame_desc() and changing the
  interface to return the frame descriptor.

- Check for descriptor type early in v4l2_subdev_get_frame_desc().

- Return 0 instead of ret in v4l2_subdev_get_frame_desc() when ret is 0.

- Check the number of returned entries in v4l2_subdev_get_frame_desc().

- Fill in the first frame descriptor entry in v4l2_subdev_get_frame_desc()
  instead of allocating one in the stack.

- Move the definition of frame descriptors to the
  v4l2_subdev_get_frame_desc() call site.

- Rework the code dealing with frame descriptor allocation.

- Move frame descriptor declaration to the location of first use in driver
  patches.

- Fix numerous bugs in driver patches.

Frank Li (1):
  media: v4l2-common: Add helper function
    media_bus_fmt_to_csi2_(bpp|dt)()

Sakari Ailus (28):
  media: v4l2-subdev: Align frame descriptor error codes with routing
  media: v4l2-subdev: Prepare for changes in getting frame descriptors
  media: v4l2-subdev: Allow releasing frame descriptors on return
  media: v4l2-subdev: Allow allocating frame descriptors based on the
    need
  media: v4l2-subdev: Change the maximum number of routes
  media: v4l2-subdev: Add frame descriptor passthrough for CSI-2 and DVP
  media: ds90ub913: Use v4l2_subdev_get_frame_desc_passthrough_csi2()
  media: ds90ub953: Use v4l2_subdev_get_frame_desc_passthrough_csi2()
  media: nxp: imx8-isi: Use
    v4l2_subdev_get_frame_desc_passthrough_csi2()
  media: rzg2l-cru: Use v4l2_subdev_get_frame_desc_passthrough_csi2()
  media: dw-mipi-csi2rx: Use
    v4l2_subdev_get_frame_desc_passthrough_csi2()
  media: cdn-csi2rc: media: Use
    v4l2_subdev_get_frame_desc_passthrough_csi2()
  media: v4l2-subdev: Make v4l2_subdev_get_frame_desc_passthrough()
    static
  media: v4l2-subdev: Return dynamically allocated pass-through routes
  media: v4l2-subdev: Always return at least one frame descriptor
  media: bcm2835-unicam: Use v4l2_subdev_get_frame_desc()
  media: bcm2835-unicam: Remove frame descriptor workaround
  media: nxp: imx8-isi: Use v4l2_subdev_get_frame_desc()
  media: raspberrypi: cfe: Use v4l2_subdev_get_frame_desc()
  media: rzg2l-cru: Use v4l2_subdev_get_frame_desc()
  media: rkisp1: Use v4l2_subdev_get_frame_desc()
  media: exynos4-is: Use v4l2_subdev_get_frame_desc()
  media: ti: cal: Use v4l2_subdev_get_frame_desc()
  media: ipu6: Use v4l2_subdev_get_frame_desc()
  staging: media: ipu7: Use v4l2_subdev_get_frame_desc()
  media: cdns-csi2rc: Use v4l2_subdev_get_frame_desc()
  media: v4l2-subdev: Use v4l2_subdev_get_frame_desc() for passthrough
  media: j721e-csi2rx: Use v4l2_subdev_get_frame_desc()

 drivers/media/i2c/ds90ub913.c                 |   2 +-
 drivers/media/i2c/ds90ub953.c                 |   2 +-
 drivers/media/pci/intel/ipu6/ipu6-isys-csi2.c |  22 +-
 .../media/platform/broadcom/bcm2835-unicam.c  |  48 ++--
 drivers/media/platform/cadence/cdns-csi2rx.c  |  26 +-
 .../platform/nxp/imx8-isi/imx8-isi-crossbar.c |  21 +-
 .../platform/nxp/imx8-isi/imx8-isi-pipe.c     |  23 +-
 .../media/platform/raspberrypi/rp1-cfe/cfe.c  |  51 +---
 .../platform/renesas/rzg2l-cru/rzg2l-csi2.c   |  21 +-
 .../platform/renesas/rzg2l-cru/rzg2l-video.c  |  27 +-
 .../platform/rockchip/rkisp1/rkisp1-isp.c     |  21 +-
 .../samsung/exynos4-is/fimc-capture.c         |  18 +-
 .../media/platform/synopsys/dw-mipi-csi2rx.c  |  22 +-
 drivers/media/platform/ti/cal/cal-camerarx.c  |  26 +-
 drivers/media/platform/ti/cal/cal.c           |  49 ++--
 .../platform/ti/j721e-csi2rx/j721e-csi2rx.c   |  32 +--
 drivers/media/v4l2-core/v4l2-common.c         | 183 +++++++++++++
 drivers/media/v4l2-core/v4l2-subdev.c         | 250 ++++++++++++++----
 .../staging/media/ipu7/ipu7-isys-csi-phy.c    |  19 +-
 drivers/staging/media/ipu7/ipu7-isys-csi2.c   |  26 +-
 include/media/mipi-csi2.h                     |  24 ++
 include/media/v4l2-subdev.h                   | 118 ++++++++-
 22 files changed, 686 insertions(+), 345 deletions(-)


base-commit: 56c29fa3ee666197516a231e75aed789ae9c530d
-- 
2.47.3


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

* [PATCH v3 01/29] media: v4l2-common: Add helper function media_bus_fmt_to_csi2_(bpp|dt)()
  2026-08-24 12:14 [PATCH v3 00/29] Rework frame descriptors Sakari Ailus
@ 2026-08-24 12:14 ` Sakari Ailus
  2026-08-26 13:18   ` Linus Walleij
  2026-08-27 22:29   ` Linus Walleij
  2026-08-24 12:14 ` [PATCH v3 02/29] media: v4l2-subdev: Align frame descriptor error codes with routing Sakari Ailus
                   ` (28 subsequent siblings)
  29 siblings, 2 replies; 67+ messages in thread
From: Sakari Ailus @ 2026-08-24 12:14 UTC (permalink / raw)
  To: linux-media
  Cc: laurent.pinchart, Dave Stevenson, Jacopo Mondi, Tomi Valkeinen,
	Jai Luthra, Mehdi Djait, Mattijs Korpershoek

From: Frank Li <Frank.Li@nxp.com>

Add helper function media_bus_fmt_to_csi2_bpp() to get media bus fmt's bpp
to reduce codes such as

	static const struct imx7_csi_pixfmt pixel_formats[] = {
        {
                .fourcc = V4L2_PIX_FMT_UYVY,
                .codes  = IMX_BUS_FMTS(
                        MEDIA_BUS_FMT_UYVY8_2X8,
                        MEDIA_BUS_FMT_UYVY8_1X16
                ),
                .yuv    = true,
                .bpp    = 16,
        },
	....

.bpp can be removed from pixel_formats with this helper function.

CSI2 data type is defined by MIPI Camera Serial Interface 2 Spec Ver4.1.
See section 9.4.

Add helper function media_bus_fmt_to_csi2_dt() to convert media bus fmt to
MIPI defined data type and avoid below duplicated static array in each CSI2
drivers.

	{
		.code = MEDIA_BUS_FMT_UYVY8_1X16,
		.data_type = MIPI_CSI2_DT_YUV422_8B,
	}

Only add known map for dt type. Need update media_bus_fmt_info when new
mapping used.

Signed-off-by: Frank Li <Frank.Li@nxp.com>
Co-developed-by: Sakari Ailus <sakari.ailus@linux.intel.com>
Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
---
 drivers/media/v4l2-core/v4l2-common.c | 183 ++++++++++++++++++++++++++
 include/media/mipi-csi2.h             |  24 ++++
 2 files changed, 207 insertions(+)

diff --git a/drivers/media/v4l2-core/v4l2-common.c b/drivers/media/v4l2-core/v4l2-common.c
index 65db7340ad38..f9e7e730c42e 100644
--- a/drivers/media/v4l2-core/v4l2-common.c
+++ b/drivers/media/v4l2-core/v4l2-common.c
@@ -46,6 +46,7 @@
 #include <linux/uaccess.h>
 #include <asm/io.h>
 #include <asm/div64.h>
+#include <media/mipi-csi2.h>
 #include <media/v4l2-common.h>
 #include <media/v4l2-device.h>
 #include <media/v4l2-ctrls.h>
@@ -867,3 +868,185 @@ struct clk *__devm_v4l2_sensor_clk_get(struct device *dev, const char *id,
 	return clk_hw->clk;
 }
 EXPORT_SYMBOL_GPL(__devm_v4l2_sensor_clk_get);
+
+/**
+ * struct media_bus_fmt_info - information about a media bus format
+ * @code: media bus format identifier (MEDIA_BUS_FMT_*)
+ * @dt: data type define in MIPI spec (MIPI_CSI2_DT *)
+ * @bpp: bit width per pixel, which is suffix from MEDIA_BUS_FMT_*, no pad. no
+ *	 compressed data.
+ */
+struct media_bus_fmt_info {
+	u32 code;
+	u8 dt;
+	u8 bpp;
+};
+
+static const struct media_bus_fmt_info media_bus_fmt_info[] = {
+	{ .code = MEDIA_BUS_FMT_RGB444_1X12, .bpp = 12 },
+	{ .code = MEDIA_BUS_FMT_RGB444_2X8_PADHI_BE, .bpp = 16 },
+	{ .code = MEDIA_BUS_FMT_RGB444_2X8_PADHI_LE, .bpp = 16 },
+	{ .code = MEDIA_BUS_FMT_RGB555_2X8_PADHI_BE, .bpp = 16 },
+	{ .code = MEDIA_BUS_FMT_RGB555_2X8_PADHI_LE, .bpp = 16 },
+	{ .code = MEDIA_BUS_FMT_RGB565_1X16, .dt = MIPI_CSI2_DT_RGB565, .bpp = 16 },
+	{ .code = MEDIA_BUS_FMT_BGR565_2X8_BE, .dt = MIPI_CSI2_DT_RGB565, .bpp = 16 },
+	{ .code = MEDIA_BUS_FMT_BGR565_2X8_LE, .dt = MIPI_CSI2_DT_RGB565, .bpp = 16 },
+	{ .code = MEDIA_BUS_FMT_RGB565_2X8_BE, .dt = MIPI_CSI2_DT_RGB565, .bpp = 16 },
+	{ .code = MEDIA_BUS_FMT_RGB565_2X8_LE, .dt = MIPI_CSI2_DT_RGB565, .bpp = 16 },
+	{ .code = MEDIA_BUS_FMT_RGB666_1X18, .bpp = 18 },
+	{ .code = MEDIA_BUS_FMT_RGB666_2X9_BE, .bpp = 18 },
+	{ .code = MEDIA_BUS_FMT_BGR666_1X18, .bpp = 18 },
+	{ .code = MEDIA_BUS_FMT_RBG888_1X24, .dt = MIPI_CSI2_DT_RGB888, .bpp = 24 },
+	{ .code = MEDIA_BUS_FMT_RGB666_1X24_CPADHI, .dt = MIPI_CSI2_DT_RGB888, .bpp = 24 },
+	{ .code = MEDIA_BUS_FMT_BGR666_1X24_CPADHI, .dt = MIPI_CSI2_DT_RGB888, .bpp = 24 },
+	{ .code = MEDIA_BUS_FMT_RGB565_1X24_CPADHI, .dt = MIPI_CSI2_DT_RGB888, .bpp = 24 },
+	{ .code = MEDIA_BUS_FMT_RGB666_1X7X3_SPWG, .bpp = 21 },
+	{ .code = MEDIA_BUS_FMT_BGR888_1X24, .dt = MIPI_CSI2_DT_RGB888, .bpp = 24 },
+	{ .code = MEDIA_BUS_FMT_BGR888_3X8, .dt = MIPI_CSI2_DT_RGB888, .bpp = 24 },
+	{ .code = MEDIA_BUS_FMT_GBR888_1X24, .dt = MIPI_CSI2_DT_RGB888, .bpp = 24 },
+	{ .code = MEDIA_BUS_FMT_RGB888_1X24, .dt = MIPI_CSI2_DT_RGB888, .bpp = 24 },
+	{ .code = MEDIA_BUS_FMT_RGB888_2X12_BE, .bpp = 24 },
+	{ .code = MEDIA_BUS_FMT_RGB888_2X12_LE, .bpp = 24 },
+	{ .code = MEDIA_BUS_FMT_RGB888_3X8, .dt = MIPI_CSI2_DT_RGB888, .bpp = 24 },
+	{ .code = MEDIA_BUS_FMT_RGB888_3X8_DELTA, .bpp = 24 },
+	{ .code = MEDIA_BUS_FMT_RGB888_1X7X4_SPWG, .bpp = 28 },
+	{ .code = MEDIA_BUS_FMT_RGB888_1X7X4_JEIDA, .bpp = 28 },
+	{ .code = MEDIA_BUS_FMT_RGB666_1X30_CPADLO, .bpp = 30 },
+	{ .code = MEDIA_BUS_FMT_RGB888_1X30_CPADLO, .bpp = 30 },
+	{ .code = MEDIA_BUS_FMT_ARGB8888_1X32, .bpp = 32 },
+	{ .code = MEDIA_BUS_FMT_RGB888_1X32_PADHI, .bpp = 32 },
+	{ .code = MEDIA_BUS_FMT_RGB101010_1X30, .bpp = 30 },
+	{ .code = MEDIA_BUS_FMT_RGB101010_1X7X5_SPWG, .bpp = 35 },
+	{ .code = MEDIA_BUS_FMT_RGB101010_1X7X5_JEIDA, .bpp = 35 },
+	{ .code = MEDIA_BUS_FMT_RGB666_1X36_CPADLO, .bpp = 36 },
+	{ .code = MEDIA_BUS_FMT_RGB888_1X36_CPADLO, .bpp = 36 },
+	{ .code = MEDIA_BUS_FMT_RGB121212_1X36, .bpp = 36 },
+	{ .code = MEDIA_BUS_FMT_RGB161616_1X48, .bpp = 48 },
+
+	{ .code = MEDIA_BUS_FMT_Y8_1X8, .dt = MIPI_CSI2_DT_RAW8, .bpp = 8 },
+	{ .code = MEDIA_BUS_FMT_UV8_1X8, .bpp = 8 },
+	{ .code = MEDIA_BUS_FMT_UYVY8_1_5X8, .bpp = 12 },
+	{ .code = MEDIA_BUS_FMT_VYUY8_1_5X8, .bpp = 12 },
+	{ .code = MEDIA_BUS_FMT_YUYV8_1_5X8, .bpp = 12 },
+	{ .code = MEDIA_BUS_FMT_YVYU8_1_5X8, .bpp = 12 },
+	{ .code = MEDIA_BUS_FMT_UYVY8_2X8, .dt = MIPI_CSI2_DT_YUV422_8B, .bpp = 16 },
+	{ .code = MEDIA_BUS_FMT_VYUY8_2X8, .dt = MIPI_CSI2_DT_YUV422_8B, .bpp = 16 },
+	{ .code = MEDIA_BUS_FMT_YUYV8_2X8, .dt = MIPI_CSI2_DT_YUV422_8B, .bpp = 16 },
+	{ .code = MEDIA_BUS_FMT_YVYU8_2X8, .dt = MIPI_CSI2_DT_YUV422_8B, .bpp = 16 },
+	{ .code = MEDIA_BUS_FMT_Y10_1X10, .dt = MIPI_CSI2_DT_RAW10, .bpp = 10 },
+	{ .code = MEDIA_BUS_FMT_Y10_2X8_PADHI_LE, .bpp = 16 },
+	{ .code = MEDIA_BUS_FMT_UYVY10_2X10, .dt = MIPI_CSI2_DT_YUV422_10B, .bpp = 20 },
+	{ .code = MEDIA_BUS_FMT_VYUY10_2X10, .dt = MIPI_CSI2_DT_YUV422_10B, .bpp = 20 },
+	{ .code = MEDIA_BUS_FMT_YUYV10_2X10, .dt = MIPI_CSI2_DT_YUV422_10B, .bpp = 20 },
+	{ .code = MEDIA_BUS_FMT_YVYU10_2X10, .dt = MIPI_CSI2_DT_YUV422_10B, .bpp = 20 },
+	{ .code = MEDIA_BUS_FMT_Y12_1X12, .dt = MIPI_CSI2_DT_RAW12, .bpp = 12 },
+	{ .code = MEDIA_BUS_FMT_UYVY12_2X12, .bpp = 24 },
+	{ .code = MEDIA_BUS_FMT_VYUY12_2X12, .bpp = 24 },
+	{ .code = MEDIA_BUS_FMT_YUYV12_2X12, .bpp = 24 },
+	{ .code = MEDIA_BUS_FMT_YVYU12_2X12, .bpp = 24 },
+	{ .code = MEDIA_BUS_FMT_Y14_1X14, .dt = MIPI_CSI2_DT_RAW14, .bpp = 14 },
+	{ .code = MEDIA_BUS_FMT_Y16_1X16, .dt = MIPI_CSI2_DT_RAW16, .bpp = 16 },
+	{ .code = MEDIA_BUS_FMT_UYVY8_1X16, .dt = MIPI_CSI2_DT_YUV422_8B, .bpp = 16 },
+	{ .code = MEDIA_BUS_FMT_VYUY8_1X16, .dt = MIPI_CSI2_DT_YUV422_8B, .bpp = 16 },
+	{ .code = MEDIA_BUS_FMT_YUYV8_1X16, .dt = MIPI_CSI2_DT_YUV422_8B, .bpp = 16 },
+	{ .code = MEDIA_BUS_FMT_YVYU8_1X16, .dt = MIPI_CSI2_DT_YUV422_8B, .bpp = 16 },
+	{ .code = MEDIA_BUS_FMT_YDYUYDYV8_1X16, .bpp = 16 },
+	{ .code = MEDIA_BUS_FMT_UYVY10_1X20, .dt = MIPI_CSI2_DT_YUV422_10B, .bpp = 20 },
+	{ .code = MEDIA_BUS_FMT_VYUY10_1X20, .dt = MIPI_CSI2_DT_YUV422_10B, .bpp = 20 },
+	{ .code = MEDIA_BUS_FMT_YUYV10_1X20, .dt = MIPI_CSI2_DT_YUV422_10B, .bpp = 20 },
+	{ .code = MEDIA_BUS_FMT_YVYU10_1X20, .dt = MIPI_CSI2_DT_YUV422_10B, .bpp = 20 },
+	{ .code = MEDIA_BUS_FMT_VUY8_1X24, .bpp = 24 },
+	{ .code = MEDIA_BUS_FMT_YUV8_1X24, .bpp = 24 },
+	{ .code = MEDIA_BUS_FMT_UYYVYY8_0_5X24, .dt = MIPI_CSI2_DT_YUV420_8B, .bpp = 12 },
+	{ .code = MEDIA_BUS_FMT_UYVY12_1X24, .bpp = 24 },
+	{ .code = MEDIA_BUS_FMT_VYUY12_1X24, .bpp = 24 },
+	{ .code = MEDIA_BUS_FMT_YUYV12_1X24, .bpp = 24 },
+	{ .code = MEDIA_BUS_FMT_YVYU12_1X24, .bpp = 24 },
+	{ .code = MEDIA_BUS_FMT_YUV10_1X30, .bpp = 30 },
+	{ .code = MEDIA_BUS_FMT_UYYVYY10_0_5X30, .bpp = 15 },
+	{ .code = MEDIA_BUS_FMT_AYUV8_1X32, .bpp = 32 },
+	{ .code = MEDIA_BUS_FMT_UYYVYY12_0_5X36, .bpp = 18 },
+	{ .code = MEDIA_BUS_FMT_YUV12_1X36, .bpp = 36 },
+	{ .code = MEDIA_BUS_FMT_YUV16_1X48, .bpp = 48 },
+	{ .code = MEDIA_BUS_FMT_UYYVYY16_0_5X48, .bpp = 24 },
+
+	{ .code = MEDIA_BUS_FMT_SBGGR8_1X8, .dt = MIPI_CSI2_DT_RAW8, .bpp = 8 },
+	{ .code = MEDIA_BUS_FMT_SGBRG8_1X8, .dt = MIPI_CSI2_DT_RAW8, .bpp = 8 },
+	{ .code = MEDIA_BUS_FMT_SGRBG8_1X8, .dt = MIPI_CSI2_DT_RAW8, .bpp = 8 },
+	{ .code = MEDIA_BUS_FMT_SRGGB8_1X8, .dt = MIPI_CSI2_DT_RAW8, .bpp = 8 },
+	{ .code = MEDIA_BUS_FMT_SBGGR10_ALAW8_1X8, .bpp = 8 },
+	{ .code = MEDIA_BUS_FMT_SGBRG10_ALAW8_1X8, .bpp = 8 },
+	{ .code = MEDIA_BUS_FMT_SGRBG10_ALAW8_1X8, .bpp = 8 },
+	{ .code = MEDIA_BUS_FMT_SRGGB10_ALAW8_1X8, .bpp = 8 },
+	{ .code = MEDIA_BUS_FMT_SBGGR10_DPCM8_1X8, .bpp = 8 },
+	{ .code = MEDIA_BUS_FMT_SGBRG10_DPCM8_1X8, .bpp = 8 },
+	{ .code = MEDIA_BUS_FMT_SGRBG10_DPCM8_1X8, .bpp = 8 },
+	{ .code = MEDIA_BUS_FMT_SRGGB10_DPCM8_1X8, .bpp = 8 },
+	{ .code = MEDIA_BUS_FMT_SBGGR10_2X8_PADHI_BE, .bpp = 16 },
+	{ .code = MEDIA_BUS_FMT_SBGGR10_2X8_PADHI_LE, .bpp = 16 },
+	{ .code = MEDIA_BUS_FMT_SBGGR10_2X8_PADLO_BE, .bpp = 16 },
+	{ .code = MEDIA_BUS_FMT_SBGGR10_2X8_PADLO_LE, .bpp = 16 },
+	{ .code = MEDIA_BUS_FMT_SBGGR10_1X10, .dt = MIPI_CSI2_DT_RAW10, .bpp = 10 },
+	{ .code = MEDIA_BUS_FMT_SGBRG10_1X10, .dt = MIPI_CSI2_DT_RAW10, .bpp = 10 },
+	{ .code = MEDIA_BUS_FMT_SGRBG10_1X10, .dt = MIPI_CSI2_DT_RAW10, .bpp = 10 },
+	{ .code = MEDIA_BUS_FMT_SRGGB10_1X10, .dt = MIPI_CSI2_DT_RAW10, .bpp = 10 },
+	{ .code = MEDIA_BUS_FMT_SBGGR12_1X12, .dt = MIPI_CSI2_DT_RAW12, .bpp = 12 },
+	{ .code = MEDIA_BUS_FMT_SGBRG12_1X12, .dt = MIPI_CSI2_DT_RAW12, .bpp = 12 },
+	{ .code = MEDIA_BUS_FMT_SGRBG12_1X12, .dt = MIPI_CSI2_DT_RAW12, .bpp = 12 },
+	{ .code = MEDIA_BUS_FMT_SRGGB12_1X12, .dt = MIPI_CSI2_DT_RAW12, .bpp = 12 },
+	{ .code = MEDIA_BUS_FMT_SBGGR14_1X14, .dt = MIPI_CSI2_DT_RAW14, .bpp = 14 },
+	{ .code = MEDIA_BUS_FMT_SGBRG14_1X14, .dt = MIPI_CSI2_DT_RAW14, .bpp = 14 },
+	{ .code = MEDIA_BUS_FMT_SGRBG14_1X14, .dt = MIPI_CSI2_DT_RAW14, .bpp = 14 },
+	{ .code = MEDIA_BUS_FMT_SRGGB14_1X14, .dt = MIPI_CSI2_DT_RAW14, .bpp = 14 },
+	{ .code = MEDIA_BUS_FMT_SBGGR16_1X16, .dt = MIPI_CSI2_DT_RAW16, .bpp = 16 },
+	{ .code = MEDIA_BUS_FMT_SGBRG16_1X16, .dt = MIPI_CSI2_DT_RAW16, .bpp = 16 },
+	{ .code = MEDIA_BUS_FMT_SGRBG16_1X16, .dt = MIPI_CSI2_DT_RAW16, .bpp = 16 },
+	{ .code = MEDIA_BUS_FMT_SRGGB16_1X16, .dt = MIPI_CSI2_DT_RAW16, .bpp = 16 },
+
+	{ .code = MEDIA_BUS_FMT_JPEG_1X8, .bpp = 8 },
+
+	{ .code = MEDIA_BUS_FMT_S5C_UYVY_JPEG_1X8, .bpp = 8 },
+
+	{ .code = MEDIA_BUS_FMT_AHSV8888_1X32, .bpp = 32 },
+
+	{ .code = MEDIA_BUS_FMT_META_8, .dt = MIPI_CSI2_DT_EMBEDDED_8B, .bpp = 8 },
+	{ .code = MEDIA_BUS_FMT_META_10, .dt = MIPI_CSI2_DT_EMBEDDED_8B, .bpp = 10 },
+	{ .code = MEDIA_BUS_FMT_META_12, .dt = MIPI_CSI2_DT_EMBEDDED_8B, .bpp = 12 },
+	{ .code = MEDIA_BUS_FMT_META_14, .dt = MIPI_CSI2_DT_EMBEDDED_8B, .bpp = 14 },
+	{ .code = MEDIA_BUS_FMT_META_16, .dt = MIPI_CSI2_DT_EMBEDDED_8B, .bpp = 16 },
+	{ .code = MEDIA_BUS_FMT_META_20, .dt = MIPI_CSI2_DT_EMBEDDED_8B, .bpp = 20 },
+	{ .code = MEDIA_BUS_FMT_META_24, .dt = MIPI_CSI2_DT_EMBEDDED_8B, .bpp = 24 },
+};
+
+static const struct media_bus_fmt_info *media_bus_fmt_info_get(u32 bus_fmt)
+{
+	for (unsigned int i = 0; i < ARRAY_SIZE(media_bus_fmt_info); i++) {
+		if (media_bus_fmt_info[i].code == bus_fmt)
+			return &media_bus_fmt_info[i];
+	}
+
+	return NULL;
+}
+
+int media_bus_fmt_to_csi2_dt(u32 bus_fmt)
+{
+	const struct media_bus_fmt_info *info = media_bus_fmt_info_get(bus_fmt);
+
+	if (!info)
+		return -EINVAL;
+
+	/* Check bpp because 0 (MIPI_CSI2_DT_FS) is a valid data type code */
+	return info->bpp ? info->dt : -EINVAL;
+}
+EXPORT_SYMBOL_GPL(media_bus_fmt_to_csi2_dt);
+
+int media_bus_fmt_to_csi2_bpp(u32 bus_fmt)
+{
+	const struct media_bus_fmt_info *info = media_bus_fmt_info_get(bus_fmt);
+
+	if (!info)
+		return -EINVAL;
+
+	return info->bpp ? info->bpp : -EINVAL;
+}
+EXPORT_SYMBOL_GPL(media_bus_fmt_to_csi2_bpp);
diff --git a/include/media/mipi-csi2.h b/include/media/mipi-csi2.h
index 40fc0264250d..86601c9824bc 100644
--- a/include/media/mipi-csi2.h
+++ b/include/media/mipi-csi2.h
@@ -8,6 +8,8 @@
 #ifndef _MEDIA_MIPI_CSI2_H
 #define _MEDIA_MIPI_CSI2_H
 
+#include <linux/types.h>
+
 /* Short packet data types */
 #define MIPI_CSI2_DT_FS			0x00
 #define MIPI_CSI2_DT_FE			0x01
@@ -44,4 +46,26 @@
 #define MIPI_CSI2_DT_RAW20		0x2f
 #define MIPI_CSI2_DT_USER_DEFINED(n)	(0x30 + (n))	/* 0..7 */
 
+/**
+ * media_bus_fmt_to_csi2_dt - Get MIPI CSI2 data type from media bus format
+ *
+ * @bus_fmt: media bus format identifier (MEDIA_BUS_FMT_*)
+ *
+ * Return: MIPI CSI2 data type MIPI_CSI2_DT_*, or -EINVAL if no mbus code is
+ * found..
+ */
+int media_bus_fmt_to_csi2_dt(u32 bus_fmt);
+
+/**
+ * media_bus_fmt_to_csi2_bpp - Get media bus format's bit depth
+ *
+ * @bus_fmt: media bus format identifier (MEDIA_BUS_FMT_*)
+ *
+ * Return: bit depth, -EINVAL if fail to get from bus_fmt.
+ *
+ * Notes: this bpp is suffix from MEDIA_BUS_FMT_*, no pad, not for compressed
+ * data.
+ */
+int media_bus_fmt_to_csi2_bpp(u32 bus_fmt);
+
 #endif /* _MEDIA_MIPI_CSI2_H */
-- 
2.47.3


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

* [PATCH v3 02/29] media: v4l2-subdev: Align frame descriptor error codes with routing
  2026-08-24 12:14 [PATCH v3 00/29] Rework frame descriptors Sakari Ailus
  2026-08-24 12:14 ` [PATCH v3 01/29] media: v4l2-common: Add helper function media_bus_fmt_to_csi2_(bpp|dt)() Sakari Ailus
@ 2026-08-24 12:14 ` Sakari Ailus
  2026-08-27  7:46   ` Linus Walleij
  2026-08-24 12:14 ` [PATCH v3 03/29] media: v4l2-subdev: Prepare for changes in getting frame descriptors Sakari Ailus
                   ` (27 subsequent siblings)
  29 siblings, 1 reply; 67+ messages in thread
From: Sakari Ailus @ 2026-08-24 12:14 UTC (permalink / raw)
  To: linux-media
  Cc: laurent.pinchart, Dave Stevenson, Jacopo Mondi, Tomi Valkeinen,
	Jai Luthra, Mehdi Djait, Mattijs Korpershoek

__v4l2_subdev_get_frame_desc_passthrough() returns -ENOSPC when there are
too many routes. There's a subtle difference when compared to -E2BIG, but
-E2BIG can be used in this case as well. In practice this was unlikely to
having been ever returned from the kernel as things currently stand.

Align the error codes with the routing IOCTLs.

Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
Reviewed-by: Frank Li <Frank.Li@nxp.com>
---
 drivers/media/v4l2-core/v4l2-subdev.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/media/v4l2-core/v4l2-subdev.c b/drivers/media/v4l2-core/v4l2-subdev.c
index e9f81b9be9e2..d93ed50255ed 100644
--- a/drivers/media/v4l2-core/v4l2-subdev.c
+++ b/drivers/media/v4l2-core/v4l2-subdev.c
@@ -2639,7 +2639,7 @@ int __v4l2_subdev_get_frame_desc_passthrough(struct v4l2_subdev *sd,
 
 			if (fd->num_entries >= V4L2_FRAME_DESC_ENTRY_MAX) {
 				dev_dbg(dev, "Frame desc entry limit reached\n");
-				return -ENOSPC;
+				return -E2BIG;
 			}
 
 			fd->entry[fd->num_entries] = *source_entry;
-- 
2.47.3


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

* [PATCH v3 03/29] media: v4l2-subdev: Prepare for changes in getting frame descriptors
  2026-08-24 12:14 [PATCH v3 00/29] Rework frame descriptors Sakari Ailus
  2026-08-24 12:14 ` [PATCH v3 01/29] media: v4l2-common: Add helper function media_bus_fmt_to_csi2_(bpp|dt)() Sakari Ailus
  2026-08-24 12:14 ` [PATCH v3 02/29] media: v4l2-subdev: Align frame descriptor error codes with routing Sakari Ailus
@ 2026-08-24 12:14 ` Sakari Ailus
  2026-08-24 12:14 ` [PATCH v3 04/29] media: v4l2-subdev: Allow releasing frame descriptors on return Sakari Ailus
                   ` (26 subsequent siblings)
  29 siblings, 0 replies; 67+ messages in thread
From: Sakari Ailus @ 2026-08-24 12:14 UTC (permalink / raw)
  To: linux-media
  Cc: laurent.pinchart, Dave Stevenson, Jacopo Mondi, Tomi Valkeinen,
	Jai Luthra, Mehdi Djait, Mattijs Korpershoek

Introduce v4l2_subdev_alloc_frame_desc() and v4l2_subdev_free_frame_desc()
to both facilitate implementing drivers that need frame descriptors as
well as prepare for having a larger number of frame descriptors.
If the remote sub-device does not support frame descriptors,
v4l2_subdev_get_frame_desc() creates one (with a single entry)
opportunistically, thus avoiding the need to add frame descriptor support
to sensor drivers the device for which only generates a single stream, or
managing the situation on the caller side.

Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
Reviewed-by: Frank Li <Frank.Li@nxp.com>
---
 drivers/media/v4l2-core/v4l2-subdev.c | 75 +++++++++++++++++++++++++++
 include/media/v4l2-subdev.h           | 34 ++++++++++++
 2 files changed, 109 insertions(+)

diff --git a/drivers/media/v4l2-core/v4l2-subdev.c b/drivers/media/v4l2-core/v4l2-subdev.c
index d93ed50255ed..a5c53dc8c396 100644
--- a/drivers/media/v4l2-core/v4l2-subdev.c
+++ b/drivers/media/v4l2-core/v4l2-subdev.c
@@ -20,6 +20,7 @@
 #include <linux/version.h>
 #include <linux/videodev2.h>
 
+#include <media/mipi-csi2.h>
 #include <media/v4l2-ctrls.h>
 #include <media/v4l2-device.h>
 #include <media/v4l2-event.h>
@@ -2671,6 +2672,80 @@ int v4l2_subdev_get_frame_desc_passthrough(struct v4l2_subdev *sd,
 }
 EXPORT_SYMBOL_GPL(v4l2_subdev_get_frame_desc_passthrough);
 
+struct v4l2_mbus_frame_desc *
+v4l2_subdev_get_frame_desc(struct v4l2_subdev *sd, unsigned int pad,
+			   enum v4l2_mbus_frame_desc_type type)
+{
+	int ret;
+
+	if (type != V4L2_MBUS_FRAME_DESC_TYPE_PARALLEL &&
+	    type != V4L2_MBUS_FRAME_DESC_TYPE_CSI2)
+		return ERR_PTR(-EINVAL);
+
+	struct v4l2_mbus_frame_desc *desc = kzalloc_obj(*desc, GFP_KERNEL);
+	if (!desc)
+		return ERR_PTR(-ENOMEM);
+
+	desc->type = type;
+
+	if (v4l2_subdev_has_op(sd, pad, get_frame_desc)) {
+		unsigned int type = desc->type;
+
+		ret = v4l2_subdev_call(sd, pad, get_frame_desc, pad, desc);
+		if (ret < 0)
+			goto err_free;
+
+		if (desc->type != type) {
+			dev_dbg(sd->dev,
+				"wrong type of frame descriptor for pad %d (got %u, expected %u)\n",
+				pad, desc->type, type);
+			ret = -EINVAL;
+			goto err_free;
+		}
+
+		return desc;
+	}
+
+	struct v4l2_subdev_format subdev_fmt = {
+		.which = V4L2_SUBDEV_FORMAT_ACTIVE,
+		.pad = pad,
+	};
+	struct v4l2_subdev_state *state =
+		v4l2_subdev_lock_and_get_active_state(sd);
+	ret = v4l2_subdev_call(sd, pad, get_fmt, state, &subdev_fmt);
+	v4l2_subdev_unlock_state(state);
+	if (ret < 0)
+		goto err_free;
+
+	struct v4l2_mbus_frame_desc_entry *entry = &desc->entry[0];
+
+	entry->pixelcode = subdev_fmt.format.code;
+
+	if (desc->type == V4L2_MBUS_FRAME_DESC_TYPE_CSI2) {
+		ret = media_bus_fmt_to_csi2_dt(subdev_fmt.format.code);
+		if (ret < 0)
+			goto err_free;
+
+		entry->bus.csi2.dt = ret;
+	}
+
+	desc->num_entries = 1;
+
+	return desc;
+
+err_free:
+	v4l2_subdev_free_frame_desc(desc);
+
+	return ERR_PTR(ret);
+}
+EXPORT_SYMBOL_GPL(v4l2_subdev_get_frame_desc);
+
+void v4l2_subdev_free_frame_desc(struct v4l2_mbus_frame_desc *desc)
+{
+	kfree(desc);
+}
+EXPORT_SYMBOL_GPL(v4l2_subdev_free_frame_desc);
+
 #endif /* CONFIG_VIDEO_V4L2_SUBDEV_API */
 
 #endif /* CONFIG_MEDIA_CONTROLLER */
diff --git a/include/media/v4l2-subdev.h b/include/media/v4l2-subdev.h
index d256b7ec8f84..e7127953ac22 100644
--- a/include/media/v4l2-subdev.h
+++ b/include/media/v4l2-subdev.h
@@ -8,6 +8,7 @@
 #ifndef _V4L2_SUBDEV_H
 #define _V4L2_SUBDEV_H
 
+#include <linux/cleanup.h>
 #include <linux/types.h>
 #include <linux/v4l2-subdev.h>
 #include <media/media-entity.h>
@@ -1778,6 +1779,39 @@ int v4l2_subdev_get_frame_desc_passthrough(struct v4l2_subdev *sd,
 					   unsigned int pad,
 					   struct v4l2_mbus_frame_desc *fd);
 
+/**
+ * v4l2_subdev_get_frame_desc() - Get a frame descriptor for a pad
+ * @sd: The sub-device
+ * @pad: The number of the pad in @sd from which to obtain the frame descriptor
+ * @type: The type of the frame descriptor
+ *
+ * Obtain a frame descriptor from a sub-device. If the sub-device supports the
+ * get_frame_desc pad operation, its result is returned, just like calling it
+ * directly using v4l2_subdev_call(). If the sub-device driver does not support
+ * it, then a frame descriptor containing a single entry is created using the
+ * information from the sub-device format for types
+ * V4L2_MBUS_FRAME_DESC_TYPE_CSI2 and V4L2_MBUS_FRAME_DESC_TYPE_PARALLEL.
+ *
+ * The caller is required to set @desc->type to the expected bus type.
+ *
+ * The caller is required to release the memory of the frame descriptor entries
+ * for each frame descriptor obtained by calling this function using
+ * v4l2_subdev_free_frame_desc().
+ *
+ * Return: The frame descriptor on success or a negative error code on failure.
+ */
+struct v4l2_mbus_frame_desc *
+v4l2_subdev_get_frame_desc(struct v4l2_subdev *sd, unsigned int pad,
+			   enum v4l2_mbus_frame_desc_type type);
+
+/**
+ * v4l2_subdev_free_frame_desc() - Release the memory of a frame descriptor
+ * @desc: A pointer to a frame descriptor
+ *
+ * Release the frame descriptor.
+ */
+void v4l2_subdev_free_frame_desc(struct v4l2_mbus_frame_desc *desc);
+
 #endif /* CONFIG_VIDEO_V4L2_SUBDEV_API */
 
 #endif /* CONFIG_MEDIA_CONTROLLER */
-- 
2.47.3


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

* [PATCH v3 04/29] media: v4l2-subdev: Allow releasing frame descriptors on return
  2026-08-24 12:14 [PATCH v3 00/29] Rework frame descriptors Sakari Ailus
                   ` (2 preceding siblings ...)
  2026-08-24 12:14 ` [PATCH v3 03/29] media: v4l2-subdev: Prepare for changes in getting frame descriptors Sakari Ailus
@ 2026-08-24 12:14 ` Sakari Ailus
  2026-08-24 20:34   ` Frank Li
  2026-08-24 12:14 ` [PATCH v3 05/29] media: v4l2-subdev: Allow allocating frame descriptors based on the need Sakari Ailus
                   ` (25 subsequent siblings)
  29 siblings, 1 reply; 67+ messages in thread
From: Sakari Ailus @ 2026-08-24 12:14 UTC (permalink / raw)
  To: linux-media
  Cc: laurent.pinchart, Dave Stevenson, Jacopo Mondi, Tomi Valkeinen,
	Jai Luthra, Mehdi Djait, Mattijs Korpershoek

Use DEFINE_FREE() to allow using __free() to release frame descriptors
using v4l2_subdev_free_frame_desc().

Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
---
 include/media/v4l2-subdev.h | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/include/media/v4l2-subdev.h b/include/media/v4l2-subdev.h
index e7127953ac22..c10ca3f5d979 100644
--- a/include/media/v4l2-subdev.h
+++ b/include/media/v4l2-subdev.h
@@ -1798,6 +1798,11 @@ int v4l2_subdev_get_frame_desc_passthrough(struct v4l2_subdev *sd,
  * for each frame descriptor obtained by calling this function using
  * v4l2_subdev_free_frame_desc().
  *
+ * Use __free() to release the frame descriptor automatically::
+ *
+ *    struct v4l2_mbus_frame_desc *desc __free(v4l2_subdev_free_frame_desc) =
+ *            v4l2_subdev_get_frame_desc(sd, pad, desc);
+ *
  * Return: The frame descriptor on success or a negative error code on failure.
  */
 struct v4l2_mbus_frame_desc *
@@ -1812,6 +1817,10 @@ v4l2_subdev_get_frame_desc(struct v4l2_subdev *sd, unsigned int pad,
  */
 void v4l2_subdev_free_frame_desc(struct v4l2_mbus_frame_desc *desc);
 
+DEFINE_FREE(v4l2_subdev_free_frame_desc, struct v4l2_mbus_frame_desc *, \
+	    if (!IS_ERR_OR_NULL(_T))					\
+		    v4l2_subdev_free_frame_desc(_T))
+
 #endif /* CONFIG_VIDEO_V4L2_SUBDEV_API */
 
 #endif /* CONFIG_MEDIA_CONTROLLER */
-- 
2.47.3


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

* [PATCH v3 05/29] media: v4l2-subdev: Allow allocating frame descriptors based on the need
  2026-08-24 12:14 [PATCH v3 00/29] Rework frame descriptors Sakari Ailus
                   ` (3 preceding siblings ...)
  2026-08-24 12:14 ` [PATCH v3 04/29] media: v4l2-subdev: Allow releasing frame descriptors on return Sakari Ailus
@ 2026-08-24 12:14 ` Sakari Ailus
  2026-08-24 12:14 ` [PATCH v3 06/29] media: v4l2-subdev: Change the maximum number of routes Sakari Ailus
                   ` (24 subsequent siblings)
  29 siblings, 0 replies; 67+ messages in thread
From: Sakari Ailus @ 2026-08-24 12:14 UTC (permalink / raw)
  To: linux-media
  Cc: laurent.pinchart, Dave Stevenson, Jacopo Mondi, Tomi Valkeinen,
	Jai Luthra, Mehdi Djait, Mattijs Korpershoek

Frame descriptors entries require a small amount of memory per entry (20
bytes), but if the number of entries in a frame descriptor is large, an
unreasonably large amount of memory would need to be allocated in the
stack. Therefore the number of entries has been limited to 8.

Support larger frame descriptors by making the entry field a pointer that
by default points to a pre-allocated array while the get_frame_desc() pad
o may allocate as much memory as required, up to V4L2_FRAME_DESC_ENTRY_MAX
which is changed to 64.

The caller is also responsible for releasing the allocated memory by
calling v4l2_subdev_free_frame_desc().

Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
Reviewed-by: Frank Li <Frank.Li@nxp.com>
---
 drivers/media/v4l2-core/v4l2-subdev.c | 45 ++++++++++++++++++++-------
 include/media/v4l2-subdev.h           | 42 ++++++++++++++++++-------
 2 files changed, 63 insertions(+), 24 deletions(-)

diff --git a/drivers/media/v4l2-core/v4l2-subdev.c b/drivers/media/v4l2-core/v4l2-subdev.c
index a5c53dc8c396..e15d3f63e004 100644
--- a/drivers/media/v4l2-core/v4l2-subdev.c
+++ b/drivers/media/v4l2-core/v4l2-subdev.c
@@ -63,10 +63,6 @@ static bool v4l2_subdev_enable_streams_api;
 /*
  * Maximum stream ID is 63 for now, as we use u64 bitmask to represent a set
  * of streams.
- *
- * Note that V4L2_FRAME_DESC_ENTRY_MAX is related: V4L2_FRAME_DESC_ENTRY_MAX
- * restricts the total number of streams in a pad, although the stream ID is
- * not restricted.
  */
 #define V4L2_SUBDEV_MAX_STREAM_ID 63
 
@@ -354,6 +350,7 @@ static int call_set_frame_interval(struct v4l2_subdev *sd,
 static int call_get_frame_desc(struct v4l2_subdev *sd, unsigned int pad,
 			       struct v4l2_mbus_frame_desc *fd)
 {
+	unsigned int type;
 	unsigned int i;
 	int ret;
 
@@ -362,16 +359,26 @@ static int call_get_frame_desc(struct v4l2_subdev *sd, unsigned int pad,
 		return -EOPNOTSUPP;
 #endif
 
-	memset(fd, 0, sizeof(*fd));
+	type = fd->type;
+	memset_after(fd, 0, type);
+	fd->entry = fd->entry_mem;
+	fd->len_entries = ARRAY_SIZE(fd->entry_mem);
 
 	ret = sd->ops->pad->get_frame_desc(sd, pad, fd);
 	if (ret)
 		return ret;
 
+	if (type == V4L2_MBUS_FRAME_DESC_TYPE_UNDEFINED) {
+		type = fd->type;
+	} else if (type != fd->type) {
+		dev_dbg(sd->dev, "Expected frame descriptor type %u, got %u\n",
+			type, fd->type);
+		return -EINVAL;
+	}
+
 	dev_dbg(sd->dev, "Frame descriptor on pad %u, type %s\n", pad,
-		fd->type == V4L2_MBUS_FRAME_DESC_TYPE_PARALLEL ? "parallel" :
-		fd->type == V4L2_MBUS_FRAME_DESC_TYPE_CSI2 ? "CSI-2" :
-		"unknown");
+		type == V4L2_MBUS_FRAME_DESC_TYPE_PARALLEL ? "parallel" :
+		type == V4L2_MBUS_FRAME_DESC_TYPE_CSI2 ? "CSI-2" : "unknown");
 
 	for (i = 0; i < fd->num_entries; i++) {
 		struct v4l2_mbus_frame_desc_entry *entry = &fd->entry[i];
@@ -1086,9 +1093,9 @@ static long subdev_do_ioctl(struct file *file, unsigned int cmd, void *arg,
 		 * descriptor accordingly, with up to one entry per route. Until
 		 * the frame descriptors entries get allocated dynamically,
 		 * limit the number of active routes to
-		 * V4L2_FRAME_DESC_ENTRY_MAX.
+		 * V4L2_FRAME_DESC_ENTRY_PREALLOC.
 		 */
-		if (num_active_routes > V4L2_FRAME_DESC_ENTRY_MAX)
+		if (num_active_routes > V4L2_FRAME_DESC_ENTRY_PREALLOC)
 			return -E2BIG;
 
 		/*
@@ -2638,7 +2645,7 @@ int __v4l2_subdev_get_frame_desc_passthrough(struct v4l2_subdev *sd,
 				return -EPIPE;
 			}
 
-			if (fd->num_entries >= V4L2_FRAME_DESC_ENTRY_MAX) {
+			if (fd->num_entries >= V4L2_FRAME_DESC_ENTRY_PREALLOC) {
 				dev_dbg(dev, "Frame desc entry limit reached\n");
 				return -E2BIG;
 			}
@@ -2703,6 +2710,14 @@ v4l2_subdev_get_frame_desc(struct v4l2_subdev *sd, unsigned int pad,
 			goto err_free;
 		}
 
+		if (desc->num_entries > desc->len_entries) {
+			dev_dbg(sd->dev,
+				"too many frame descriptors; got %u, expected at most %u\n",
+				desc->num_entries, desc->len_entries);
+			ret = -EINVAL;
+			goto err_free;
+		}
+
 		return desc;
 	}
 
@@ -2717,7 +2732,10 @@ v4l2_subdev_get_frame_desc(struct v4l2_subdev *sd, unsigned int pad,
 	if (ret < 0)
 		goto err_free;
 
-	struct v4l2_mbus_frame_desc_entry *entry = &desc->entry[0];
+	desc->entry = desc->entry_mem;
+	desc->len_entries = ARRAY_SIZE(desc->entry_mem);
+
+	struct v4l2_mbus_frame_desc_entry *entry = desc->entry;
 
 	entry->pixelcode = subdev_fmt.format.code;
 
@@ -2742,6 +2760,9 @@ EXPORT_SYMBOL_GPL(v4l2_subdev_get_frame_desc);
 
 void v4l2_subdev_free_frame_desc(struct v4l2_mbus_frame_desc *desc)
 {
+	if (desc->entry != desc->entry_mem)
+		kfree(desc->entry);
+
 	kfree(desc);
 }
 EXPORT_SYMBOL_GPL(v4l2_subdev_free_frame_desc);
diff --git a/include/media/v4l2-subdev.h b/include/media/v4l2-subdev.h
index c10ca3f5d979..daebf8982c43 100644
--- a/include/media/v4l2-subdev.h
+++ b/include/media/v4l2-subdev.h
@@ -366,11 +366,13 @@ struct v4l2_mbus_frame_desc_entry {
 	} bus;
 };
 
- /*
-  * If this number is too small, it should be dropped altogether and the
-  * API switched to a dynamic number of frame descriptor entries.
-  */
-#define V4L2_FRAME_DESC_ENTRY_MAX	8
+/* Size of the statically allocated frame descriptor array. */
+#define V4L2_FRAME_DESC_ENTRY_PREALLOC	8
+/*
+ * Maximum number of dynamically allocated frame descriptors. Note that
+ * V4L2_SUBDEV_MAX_STREAM_ID is related to this limit as well.
+ */
+#define V4L2_FRAME_DESC_ENTRY_MAX	64
 
 /**
  * enum v4l2_mbus_frame_desc_type - media bus frame description type
@@ -393,13 +395,17 @@ enum v4l2_mbus_frame_desc_type {
 /**
  * struct v4l2_mbus_frame_desc - media bus data frame description
  * @type: type of the bus (enum v4l2_mbus_frame_desc_type)
- * @entry: frame descriptors array
- * @num_entries: number of entries in @entry array
+ * @entry_mem: memory for the frame descriptors (@entry)
+ * @entry: pointer to the frame descriptors
+ * @num_entries: number of entries in @entry
+ * @len_entries: number of entries allocated for @entry
  */
 struct v4l2_mbus_frame_desc {
 	enum v4l2_mbus_frame_desc_type type;
-	struct v4l2_mbus_frame_desc_entry entry[V4L2_FRAME_DESC_ENTRY_MAX];
+	struct v4l2_mbus_frame_desc_entry entry_mem[V4L2_FRAME_DESC_ENTRY_PREALLOC];
+	struct v4l2_mbus_frame_desc_entry *entry;
 	unsigned short num_entries;
+	unsigned short len_entries;
 };
 
 /**
@@ -781,7 +787,17 @@ struct v4l2_subdev_state {
  * @link_validate: used by the media controller code to check if the links
  *		   that belongs to a pipeline can be used for stream.
  *
- * @get_frame_desc: get the current low level media bus frame parameters.
+ * @get_frame_desc: get the current low level media bus frame parameters. The
+ *		    callback is required to update the num_entries field to the
+ *		    total number of entries in the frame descriptor. The
+ *		    callback shall fill the first entries array up to
+ *		    len_entries, which signifies the number of entries
+ *		    allocated. If the number of entries needed exceeds
+ *		    len_entries, allocate enough memory using kzalloc_objs() or
+ *		    a similar function returning kmalloc() memory. Never call
+ *		    this directly in drivers, use v4l2_subdev_get_frame_desc()
+ *		    instead. The maximum number of num_entries is
+ *		    V4L2_FRAME_DESC_ENTRY_MAX.
  *
  * @set_frame_desc: set the low level media bus frame parameters, @fd array
  *                  may be adjusted by the subdev driver to device capabilities.
@@ -1794,8 +1810,9 @@ int v4l2_subdev_get_frame_desc_passthrough(struct v4l2_subdev *sd,
  *
  * The caller is required to set @desc->type to the expected bus type.
  *
- * The caller is required to release the memory of the frame descriptor entries
- * for each frame descriptor obtained by calling this function using
+ * The entries in the frame descriptor are allocated based on the need. The
+ * caller is required to release the memory of the frame descriptor entries for
+ * each frame descriptor obtained by calling this function using
  * v4l2_subdev_free_frame_desc().
  *
  * Use __free() to release the frame descriptor automatically::
@@ -1813,7 +1830,8 @@ v4l2_subdev_get_frame_desc(struct v4l2_subdev *sd, unsigned int pad,
  * v4l2_subdev_free_frame_desc() - Release the memory of a frame descriptor
  * @desc: A pointer to a frame descriptor
  *
- * Release the frame descriptor.
+ * Release the frame descriptor entries in a frame descriptor as well as the
+ * frame descriptor itself.
  */
 void v4l2_subdev_free_frame_desc(struct v4l2_mbus_frame_desc *desc);
 
-- 
2.47.3


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

* [PATCH v3 06/29] media: v4l2-subdev: Change the maximum number of routes
  2026-08-24 12:14 [PATCH v3 00/29] Rework frame descriptors Sakari Ailus
                   ` (4 preceding siblings ...)
  2026-08-24 12:14 ` [PATCH v3 05/29] media: v4l2-subdev: Allow allocating frame descriptors based on the need Sakari Ailus
@ 2026-08-24 12:14 ` Sakari Ailus
  2026-08-24 12:14 ` [PATCH v3 07/29] media: v4l2-subdev: Add frame descriptor passthrough for CSI-2 and DVP Sakari Ailus
                   ` (23 subsequent siblings)
  29 siblings, 0 replies; 67+ messages in thread
From: Sakari Ailus @ 2026-08-24 12:14 UTC (permalink / raw)
  To: linux-media
  Cc: laurent.pinchart, Dave Stevenson, Jacopo Mondi, Tomi Valkeinen,
	Jai Luthra, Mehdi Djait, Mattijs Korpershoek

As the frame descriptors are now allocated dynamically, allow as many
routes that there can be dynamically allocated frame descriptors.

Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
Reviewed-by: Frank Li <Frank.Li@nxp.com>
---
 drivers/media/v4l2-core/v4l2-subdev.c | 9 +--------
 1 file changed, 1 insertion(+), 8 deletions(-)

diff --git a/drivers/media/v4l2-core/v4l2-subdev.c b/drivers/media/v4l2-core/v4l2-subdev.c
index e15d3f63e004..071657459202 100644
--- a/drivers/media/v4l2-core/v4l2-subdev.c
+++ b/drivers/media/v4l2-core/v4l2-subdev.c
@@ -1088,14 +1088,7 @@ static long subdev_do_ioctl(struct file *file, unsigned int cmd, void *arg,
 				num_active_routes++;
 		}
 
-		/*
-		 * Drivers that implement routing need to report a frame
-		 * descriptor accordingly, with up to one entry per route. Until
-		 * the frame descriptors entries get allocated dynamically,
-		 * limit the number of active routes to
-		 * V4L2_FRAME_DESC_ENTRY_PREALLOC.
-		 */
-		if (num_active_routes > V4L2_FRAME_DESC_ENTRY_PREALLOC)
+		if (num_active_routes > V4L2_FRAME_DESC_ENTRY_MAX)
 			return -E2BIG;
 
 		/*
-- 
2.47.3


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

* [PATCH v3 07/29] media: v4l2-subdev: Add frame descriptor passthrough for CSI-2 and DVP
  2026-08-24 12:14 [PATCH v3 00/29] Rework frame descriptors Sakari Ailus
                   ` (5 preceding siblings ...)
  2026-08-24 12:14 ` [PATCH v3 06/29] media: v4l2-subdev: Change the maximum number of routes Sakari Ailus
@ 2026-08-24 12:14 ` Sakari Ailus
  2026-08-24 20:43   ` Frank Li
  2026-08-24 12:14 ` [PATCH v3 08/29] media: ds90ub913: Use v4l2_subdev_get_frame_desc_passthrough_csi2() Sakari Ailus
                   ` (22 subsequent siblings)
  29 siblings, 1 reply; 67+ messages in thread
From: Sakari Ailus @ 2026-08-24 12:14 UTC (permalink / raw)
  To: linux-media
  Cc: laurent.pinchart, Dave Stevenson, Jacopo Mondi, Tomi Valkeinen,
	Jai Luthra, Mehdi Djait, Mattijs Korpershoek

Add frame descriptor pass-through functions specific to MIPI CSI-2 and DVP
(parallel) interfaces. The two new functions are needed in order to
support frame descriptor-less sub-device drivers.

Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
---
 drivers/media/v4l2-core/v4l2-subdev.c | 20 +++++++++++
 include/media/v4l2-subdev.h           | 49 +++++++++++++++++++++++++++
 2 files changed, 69 insertions(+)

diff --git a/drivers/media/v4l2-core/v4l2-subdev.c b/drivers/media/v4l2-core/v4l2-subdev.c
index 071657459202..f5fa62038754 100644
--- a/drivers/media/v4l2-core/v4l2-subdev.c
+++ b/drivers/media/v4l2-core/v4l2-subdev.c
@@ -2672,6 +2672,26 @@ int v4l2_subdev_get_frame_desc_passthrough(struct v4l2_subdev *sd,
 }
 EXPORT_SYMBOL_GPL(v4l2_subdev_get_frame_desc_passthrough);
 
+int v4l2_subdev_get_frame_desc_passthrough_dvp(struct v4l2_subdev *sd,
+					       unsigned int pad,
+					       struct v4l2_mbus_frame_desc *fd)
+{
+	fd->type = V4L2_MBUS_FRAME_DESC_TYPE_PARALLEL;
+
+	return v4l2_subdev_get_frame_desc_passthrough(sd, pad, fd);
+}
+EXPORT_SYMBOL_GPL(v4l2_subdev_get_frame_desc_passthrough_dvp);
+
+int v4l2_subdev_get_frame_desc_passthrough_csi2(struct v4l2_subdev *sd,
+						unsigned int pad,
+						struct v4l2_mbus_frame_desc *fd)
+{
+	fd->type = V4L2_MBUS_FRAME_DESC_TYPE_CSI2;
+
+	return v4l2_subdev_get_frame_desc_passthrough(sd, pad, fd);
+}
+EXPORT_SYMBOL_GPL(v4l2_subdev_get_frame_desc_passthrough_csi2);
+
 struct v4l2_mbus_frame_desc *
 v4l2_subdev_get_frame_desc(struct v4l2_subdev *sd, unsigned int pad,
 			   enum v4l2_mbus_frame_desc_type type)
diff --git a/include/media/v4l2-subdev.h b/include/media/v4l2-subdev.h
index daebf8982c43..80ae7649f5c7 100644
--- a/include/media/v4l2-subdev.h
+++ b/include/media/v4l2-subdev.h
@@ -1795,6 +1795,55 @@ int v4l2_subdev_get_frame_desc_passthrough(struct v4l2_subdev *sd,
 					   unsigned int pad,
 					   struct v4l2_mbus_frame_desc *fd);
 
+/**
+ * v4l2_subdev_get_frame_desc_passthrough_dvp() - Helper to implement the subdev
+ *	get_frame_desc operation in simple passthrough cases for DVP
+ * @sd: The subdevice
+ * @pad: The source pad index
+ * @fd: The mbus frame desc
+ *
+ * This function locks the subdevice's active state, calls
+ * __v4l2_subdev_get_frame_desc_passthrough(), and unlocks the state.
+ *
+ * This function can be assigned directly as the .get_frame_desc callback in
+ * &v4l2_subdev_pad_ops for subdevices that pass streams through without
+ * modification. Drivers that need to perform additional work should use
+ * __v4l2_subdev_get_frame_desc_passthrough() in their custom
+ * .get_frame_desc implementation instead.
+ *
+ * This callback can be used for the DVP (Digital Video Port), also often called
+ * simply the "parallel interface".
+ *
+ * Return: 0 on success, or a negative error code otherwise.
+ */
+int v4l2_subdev_get_frame_desc_passthrough_dvp(struct v4l2_subdev *sd,
+					       unsigned int pad,
+					       struct v4l2_mbus_frame_desc *fd);
+
+/**
+ * v4l2_subdev_get_frame_desc_passthrough_csi2() - Helper to implement the subdev
+ *	get_frame_desc operation in simple passthrough cases for MIPI CSI-2
+ * @sd: The subdevice
+ * @pad: The source pad index
+ * @fd: The mbus frame desc
+ *
+ * This function locks the subdevice's active state, calls
+ * __v4l2_subdev_get_frame_desc_passthrough(), and unlocks the state.
+ *
+ * This function can be assigned directly as the .get_frame_desc callback in
+ * &v4l2_subdev_pad_ops for subdevices that pass streams through without
+ * modification. Drivers that need to perform additional work should use
+ * __v4l2_subdev_get_frame_desc_passthrough() in their custom
+ * .get_frame_desc implementation instead.
+ *
+ * This callback can be used for the MIPI CSI-2 interface.
+ *
+ * Return: 0 on success, or a negative error code otherwise.
+ */
+int v4l2_subdev_get_frame_desc_passthrough_csi2(struct v4l2_subdev *sd,
+						unsigned int pad,
+						struct v4l2_mbus_frame_desc *fd);
+
 /**
  * v4l2_subdev_get_frame_desc() - Get a frame descriptor for a pad
  * @sd: The sub-device
-- 
2.47.3


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

* [PATCH v3 08/29] media: ds90ub913: Use v4l2_subdev_get_frame_desc_passthrough_csi2()
  2026-08-24 12:14 [PATCH v3 00/29] Rework frame descriptors Sakari Ailus
                   ` (6 preceding siblings ...)
  2026-08-24 12:14 ` [PATCH v3 07/29] media: v4l2-subdev: Add frame descriptor passthrough for CSI-2 and DVP Sakari Ailus
@ 2026-08-24 12:14 ` Sakari Ailus
  2026-08-24 20:44   ` Frank Li
  2026-08-24 12:14 ` [PATCH v3 09/29] media: ds90ub953: " Sakari Ailus
                   ` (21 subsequent siblings)
  29 siblings, 1 reply; 67+ messages in thread
From: Sakari Ailus @ 2026-08-24 12:14 UTC (permalink / raw)
  To: linux-media
  Cc: laurent.pinchart, Dave Stevenson, Jacopo Mondi, Tomi Valkeinen,
	Jai Luthra, Mehdi Djait, Mattijs Korpershoek

Switch to v4l2_subdev_get_frame_desc_passthrough_csi2() in order to set
the frame descriptor type in the get_frame_desc() callback.

Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
---
 drivers/media/i2c/ds90ub913.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/media/i2c/ds90ub913.c b/drivers/media/i2c/ds90ub913.c
index 6abb5e324ae1..922865f03d37 100644
--- a/drivers/media/i2c/ds90ub913.c
+++ b/drivers/media/i2c/ds90ub913.c
@@ -487,7 +487,7 @@ static const struct v4l2_subdev_pad_ops ub913_pad_ops = {
 	.enable_streams = ub913_enable_streams,
 	.disable_streams = ub913_disable_streams,
 	.set_routing = ub913_set_routing,
-	.get_frame_desc = v4l2_subdev_get_frame_desc_passthrough,
+	.get_frame_desc = v4l2_subdev_get_frame_desc_passthrough_csi2,
 	.get_fmt = v4l2_subdev_get_fmt,
 	.set_fmt = ub913_set_fmt,
 };
-- 
2.47.3


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

* [PATCH v3 09/29] media: ds90ub953: Use v4l2_subdev_get_frame_desc_passthrough_csi2()
  2026-08-24 12:14 [PATCH v3 00/29] Rework frame descriptors Sakari Ailus
                   ` (7 preceding siblings ...)
  2026-08-24 12:14 ` [PATCH v3 08/29] media: ds90ub913: Use v4l2_subdev_get_frame_desc_passthrough_csi2() Sakari Ailus
@ 2026-08-24 12:14 ` Sakari Ailus
  2026-08-24 20:44   ` Frank Li
  2026-08-24 12:14 ` [PATCH v3 10/29] media: nxp: imx8-isi: " Sakari Ailus
                   ` (20 subsequent siblings)
  29 siblings, 1 reply; 67+ messages in thread
From: Sakari Ailus @ 2026-08-24 12:14 UTC (permalink / raw)
  To: linux-media
  Cc: laurent.pinchart, Dave Stevenson, Jacopo Mondi, Tomi Valkeinen,
	Jai Luthra, Mehdi Djait, Mattijs Korpershoek

Switch to v4l2_subdev_get_frame_desc_passthrough_csi2() in order to set
the frame descriptor type in the get_frame_desc() callback.

Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
---
 drivers/media/i2c/ds90ub953.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/media/i2c/ds90ub953.c b/drivers/media/i2c/ds90ub953.c
index d4228e1134ff..1ed1ae90eaae 100644
--- a/drivers/media/i2c/ds90ub953.c
+++ b/drivers/media/i2c/ds90ub953.c
@@ -635,7 +635,7 @@ static const struct v4l2_subdev_pad_ops ub953_pad_ops = {
 	.enable_streams = ub953_enable_streams,
 	.disable_streams = ub953_disable_streams,
 	.set_routing = ub953_set_routing,
-	.get_frame_desc = v4l2_subdev_get_frame_desc_passthrough,
+	.get_frame_desc = v4l2_subdev_get_frame_desc_passthrough_csi2,
 	.get_fmt = v4l2_subdev_get_fmt,
 	.set_fmt = ub953_set_fmt,
 };
-- 
2.47.3


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

* [PATCH v3 10/29] media: nxp: imx8-isi: Use v4l2_subdev_get_frame_desc_passthrough_csi2()
  2026-08-24 12:14 [PATCH v3 00/29] Rework frame descriptors Sakari Ailus
                   ` (8 preceding siblings ...)
  2026-08-24 12:14 ` [PATCH v3 09/29] media: ds90ub953: " Sakari Ailus
@ 2026-08-24 12:14 ` Sakari Ailus
  2026-08-24 20:44   ` Frank Li
  2026-08-24 12:14 ` [PATCH v3 11/29] media: rzg2l-cru: " Sakari Ailus
                   ` (19 subsequent siblings)
  29 siblings, 1 reply; 67+ messages in thread
From: Sakari Ailus @ 2026-08-24 12:14 UTC (permalink / raw)
  To: linux-media
  Cc: laurent.pinchart, Dave Stevenson, Jacopo Mondi, Tomi Valkeinen,
	Jai Luthra, Mehdi Djait, Mattijs Korpershoek

Switch to v4l2_subdev_get_frame_desc_passthrough_csi2() in order to set
the frame descriptor type in the get_frame_desc() callback.

Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
---
 drivers/media/platform/nxp/imx8-isi/imx8-isi-crossbar.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/media/platform/nxp/imx8-isi/imx8-isi-crossbar.c b/drivers/media/platform/nxp/imx8-isi/imx8-isi-crossbar.c
index 7bb1335f2110..e6c38a769205 100644
--- a/drivers/media/platform/nxp/imx8-isi/imx8-isi-crossbar.c
+++ b/drivers/media/platform/nxp/imx8-isi/imx8-isi-crossbar.c
@@ -462,7 +462,7 @@ static const struct v4l2_subdev_pad_ops mxc_isi_crossbar_subdev_pad_ops = {
 	.enum_mbus_code = mxc_isi_crossbar_enum_mbus_code,
 	.get_fmt = v4l2_subdev_get_fmt,
 	.set_fmt = mxc_isi_crossbar_set_fmt,
-	.get_frame_desc = v4l2_subdev_get_frame_desc_passthrough,
+	.get_frame_desc = v4l2_subdev_get_frame_desc_passthrough_csi2,
 	.set_routing = mxc_isi_crossbar_set_routing,
 	.enable_streams = mxc_isi_crossbar_enable_streams,
 	.disable_streams = mxc_isi_crossbar_disable_streams,
-- 
2.47.3


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

* [PATCH v3 11/29] media: rzg2l-cru: Use v4l2_subdev_get_frame_desc_passthrough_csi2()
  2026-08-24 12:14 [PATCH v3 00/29] Rework frame descriptors Sakari Ailus
                   ` (9 preceding siblings ...)
  2026-08-24 12:14 ` [PATCH v3 10/29] media: nxp: imx8-isi: " Sakari Ailus
@ 2026-08-24 12:14 ` Sakari Ailus
  2026-08-24 20:45   ` Frank Li
  2026-08-24 12:14 ` [PATCH v3 12/29] media: dw-mipi-csi2rx: " Sakari Ailus
                   ` (18 subsequent siblings)
  29 siblings, 1 reply; 67+ messages in thread
From: Sakari Ailus @ 2026-08-24 12:14 UTC (permalink / raw)
  To: linux-media
  Cc: laurent.pinchart, Dave Stevenson, Jacopo Mondi, Tomi Valkeinen,
	Jai Luthra, Mehdi Djait, Mattijs Korpershoek

Switch to v4l2_subdev_get_frame_desc_passthrough_csi2() in order to set
the frame descriptor type in the get_frame_desc() callback.

Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
---
 .../platform/renesas/rzg2l-cru/rzg2l-csi2.c   | 21 +------------------
 1 file changed, 1 insertion(+), 20 deletions(-)

diff --git a/drivers/media/platform/renesas/rzg2l-cru/rzg2l-csi2.c b/drivers/media/platform/renesas/rzg2l-cru/rzg2l-csi2.c
index 6dc4b53607b4..472154c5ca9e 100644
--- a/drivers/media/platform/renesas/rzg2l-cru/rzg2l-csi2.c
+++ b/drivers/media/platform/renesas/rzg2l-cru/rzg2l-csi2.c
@@ -722,25 +722,6 @@ static int rzg2l_csi2_enum_frame_size(struct v4l2_subdev *sd,
 	return 0;
 }
 
-static int rzg2l_csi2_get_frame_desc(struct v4l2_subdev *sd, unsigned int pad,
-				     struct v4l2_mbus_frame_desc *fd)
-{
-	struct rzg2l_csi2 *csi2 = sd_to_csi2(sd);
-	struct media_pad *remote_pad;
-
-	if (!csi2->remote_source)
-		return -ENODEV;
-
-	remote_pad = media_pad_remote_pad_unique(&csi2->pads[RZG2L_CSI2_SINK]);
-	if (IS_ERR(remote_pad)) {
-		dev_err(csi2->dev, "can't get source pad of %s (%pe)\n",
-			csi2->remote_source->name, remote_pad);
-		return PTR_ERR(remote_pad);
-	}
-	return v4l2_subdev_call(csi2->remote_source, pad, get_frame_desc,
-				remote_pad->index, fd);
-}
-
 static const struct v4l2_subdev_video_ops rzg2l_csi2_video_ops = {
 	.s_stream = rzg2l_csi2_s_stream,
 	.pre_streamon = rzg2l_csi2_pre_streamon,
@@ -752,7 +733,7 @@ static const struct v4l2_subdev_pad_ops rzg2l_csi2_pad_ops = {
 	.enum_frame_size = rzg2l_csi2_enum_frame_size,
 	.set_fmt = rzg2l_csi2_set_format,
 	.get_fmt = v4l2_subdev_get_fmt,
-	.get_frame_desc = rzg2l_csi2_get_frame_desc,
+	.get_frame_desc = v4l2_subdev_get_frame_desc_passthrough_csi2,
 };
 
 static const struct v4l2_subdev_ops rzg2l_csi2_subdev_ops = {
-- 
2.47.3


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

* [PATCH v3 12/29] media: dw-mipi-csi2rx: Use v4l2_subdev_get_frame_desc_passthrough_csi2()
  2026-08-24 12:14 [PATCH v3 00/29] Rework frame descriptors Sakari Ailus
                   ` (10 preceding siblings ...)
  2026-08-24 12:14 ` [PATCH v3 11/29] media: rzg2l-cru: " Sakari Ailus
@ 2026-08-24 12:14 ` Sakari Ailus
  2026-08-24 20:46   ` Frank Li
  2026-08-24 12:14 ` [PATCH v3 13/29] media: cdn-csi2rc: media: " Sakari Ailus
                   ` (17 subsequent siblings)
  29 siblings, 1 reply; 67+ messages in thread
From: Sakari Ailus @ 2026-08-24 12:14 UTC (permalink / raw)
  To: linux-media
  Cc: laurent.pinchart, Dave Stevenson, Jacopo Mondi, Tomi Valkeinen,
	Jai Luthra, Mehdi Djait, Mattijs Korpershoek

Switch to v4l2_subdev_get_frame_desc_passthrough_csi2() in order to set
the frame descriptor type in the get_frame_desc() callback.

Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
---
 .../media/platform/synopsys/dw-mipi-csi2rx.c  | 22 +------------------
 1 file changed, 1 insertion(+), 21 deletions(-)

diff --git a/drivers/media/platform/synopsys/dw-mipi-csi2rx.c b/drivers/media/platform/synopsys/dw-mipi-csi2rx.c
index 41e48365167e..9e3c97f9cad5 100644
--- a/drivers/media/platform/synopsys/dw-mipi-csi2rx.c
+++ b/drivers/media/platform/synopsys/dw-mipi-csi2rx.c
@@ -630,31 +630,11 @@ static int dw_mipi_csi2rx_disable_streams(struct v4l2_subdev *sd,
 	return ret;
 }
 
-static int
-dw_mipi_csi2rx_get_frame_desc(struct v4l2_subdev *sd, unsigned int pad,
-			      struct v4l2_mbus_frame_desc *fd)
-{
-	struct dw_mipi_csi2rx_device *csi2 = to_csi2(sd);
-	struct v4l2_subdev *remote_sd;
-	struct media_pad *remote_pad;
-
-	remote_pad = media_pad_remote_pad_unique(&csi2->pads[DW_MIPI_CSI2RX_PAD_SINK]);
-	if (IS_ERR(remote_pad)) {
-		dev_err(csi2->dev, "can't get remote source pad\n");
-		return PTR_ERR(remote_pad);
-	}
-
-	remote_sd = media_entity_to_v4l2_subdev(remote_pad->entity);
-
-	return v4l2_subdev_call(remote_sd, pad, get_frame_desc,
-				remote_pad->index, fd);
-}
-
 static const struct v4l2_subdev_pad_ops dw_mipi_csi2rx_pad_ops = {
 	.enum_mbus_code = dw_mipi_csi2rx_enum_mbus_code,
 	.get_fmt = v4l2_subdev_get_fmt,
 	.set_fmt = dw_mipi_csi2rx_set_fmt,
-	.get_frame_desc = dw_mipi_csi2rx_get_frame_desc,
+	.get_frame_desc = v4l2_subdev_get_frame_desc_passthrough_csi2,
 	.set_routing = dw_mipi_csi2rx_set_routing,
 	.enable_streams = dw_mipi_csi2rx_enable_streams,
 	.disable_streams = dw_mipi_csi2rx_disable_streams,
-- 
2.47.3


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

* [PATCH v3 13/29] media: cdn-csi2rc: media: Use v4l2_subdev_get_frame_desc_passthrough_csi2()
  2026-08-24 12:14 [PATCH v3 00/29] Rework frame descriptors Sakari Ailus
                   ` (11 preceding siblings ...)
  2026-08-24 12:14 ` [PATCH v3 12/29] media: dw-mipi-csi2rx: " Sakari Ailus
@ 2026-08-24 12:14 ` Sakari Ailus
  2026-08-24 20:47   ` Frank Li
  2026-08-26  6:41   ` Jai Luthra
  2026-08-24 12:14 ` [PATCH v3 14/29] media: v4l2-subdev: Make v4l2_subdev_get_frame_desc_passthrough() static Sakari Ailus
                   ` (16 subsequent siblings)
  29 siblings, 2 replies; 67+ messages in thread
From: Sakari Ailus @ 2026-08-24 12:14 UTC (permalink / raw)
  To: linux-media
  Cc: laurent.pinchart, Dave Stevenson, Jacopo Mondi, Tomi Valkeinen,
	Jai Luthra, Mehdi Djait, Mattijs Korpershoek

Switch to v4l2_subdev_get_frame_desc_passthrough_csi2() in order to allow
compatibility with drivers that do not implement get_frame_desc() pad op.

Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
---
 drivers/media/platform/cadence/cdns-csi2rx.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/media/platform/cadence/cdns-csi2rx.c b/drivers/media/platform/cadence/cdns-csi2rx.c
index 1ff2d8f78d5b..e31cdcd9ce8e 100644
--- a/drivers/media/platform/cadence/cdns-csi2rx.c
+++ b/drivers/media/platform/cadence/cdns-csi2rx.c
@@ -722,7 +722,7 @@ static const struct v4l2_subdev_pad_ops csi2rx_pad_ops = {
 	.enum_mbus_code		= csi2rx_enum_mbus_code,
 	.get_fmt		= v4l2_subdev_get_fmt,
 	.set_fmt		= csi2rx_set_fmt,
-	.get_frame_desc		= v4l2_subdev_get_frame_desc_passthrough,
+	.get_frame_desc		= v4l2_subdev_get_frame_desc_passthrough_csi2,
 	.set_routing		= csi2rx_set_routing,
 	.enable_streams		= csi2rx_enable_streams,
 	.disable_streams	= csi2rx_disable_streams,
-- 
2.47.3


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

* [PATCH v3 14/29] media: v4l2-subdev: Make v4l2_subdev_get_frame_desc_passthrough() static
  2026-08-24 12:14 [PATCH v3 00/29] Rework frame descriptors Sakari Ailus
                   ` (12 preceding siblings ...)
  2026-08-24 12:14 ` [PATCH v3 13/29] media: cdn-csi2rc: media: " Sakari Ailus
@ 2026-08-24 12:14 ` Sakari Ailus
  2026-08-24 20:48   ` Frank Li
  2026-08-24 12:14 ` [PATCH v3 15/29] media: v4l2-subdev: Return dynamically allocated pass-through routes Sakari Ailus
                   ` (15 subsequent siblings)
  29 siblings, 1 reply; 67+ messages in thread
From: Sakari Ailus @ 2026-08-24 12:14 UTC (permalink / raw)
  To: linux-media
  Cc: laurent.pinchart, Dave Stevenson, Jacopo Mondi, Tomi Valkeinen,
	Jai Luthra, Mehdi Djait, Mattijs Korpershoek

No driver uses (nor should use) v4l2_subdev_get_frame_desc_passthrough()
anymore, make it static.

Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
---
 drivers/media/v4l2-core/v4l2-subdev.c |  8 ++++----
 include/media/v4l2-subdev.h           | 22 ----------------------
 2 files changed, 4 insertions(+), 26 deletions(-)

diff --git a/drivers/media/v4l2-core/v4l2-subdev.c b/drivers/media/v4l2-core/v4l2-subdev.c
index f5fa62038754..c9f38b0313eb 100644
--- a/drivers/media/v4l2-core/v4l2-subdev.c
+++ b/drivers/media/v4l2-core/v4l2-subdev.c
@@ -2655,9 +2655,10 @@ int __v4l2_subdev_get_frame_desc_passthrough(struct v4l2_subdev *sd,
 }
 EXPORT_SYMBOL_GPL(__v4l2_subdev_get_frame_desc_passthrough);
 
-int v4l2_subdev_get_frame_desc_passthrough(struct v4l2_subdev *sd,
-					   unsigned int pad,
-					   struct v4l2_mbus_frame_desc *fd)
+static int
+v4l2_subdev_get_frame_desc_passthrough(struct v4l2_subdev *sd,
+				       unsigned int pad,
+				       struct v4l2_mbus_frame_desc *fd)
 {
 	struct v4l2_subdev_state *state;
 	int ret;
@@ -2670,7 +2671,6 @@ int v4l2_subdev_get_frame_desc_passthrough(struct v4l2_subdev *sd,
 
 	return ret;
 }
-EXPORT_SYMBOL_GPL(v4l2_subdev_get_frame_desc_passthrough);
 
 int v4l2_subdev_get_frame_desc_passthrough_dvp(struct v4l2_subdev *sd,
 					       unsigned int pad,
diff --git a/include/media/v4l2-subdev.h b/include/media/v4l2-subdev.h
index 80ae7649f5c7..cfe285f44f57 100644
--- a/include/media/v4l2-subdev.h
+++ b/include/media/v4l2-subdev.h
@@ -1773,28 +1773,6 @@ int __v4l2_subdev_get_frame_desc_passthrough(struct v4l2_subdev *sd,
 					     unsigned int pad,
 					     struct v4l2_mbus_frame_desc *fd);
 
-/**
- * v4l2_subdev_get_frame_desc_passthrough() - Helper to implement the subdev
- *	get_frame_desc operation in simple passthrough cases
- * @sd: The subdevice
- * @pad: The source pad index
- * @fd: The mbus frame desc
- *
- * This function locks the subdevice's active state, calls
- * __v4l2_subdev_get_frame_desc_passthrough(), and unlocks the state.
- *
- * This function can be assigned directly as the .get_frame_desc callback in
- * &v4l2_subdev_pad_ops for subdevices that pass streams through without
- * modification. Drivers that need to perform additional work should use
- * __v4l2_subdev_get_frame_desc_passthrough() in their custom
- * .get_frame_desc implementation instead.
- *
- * Return: 0 on success, or a negative error code otherwise.
- */
-int v4l2_subdev_get_frame_desc_passthrough(struct v4l2_subdev *sd,
-					   unsigned int pad,
-					   struct v4l2_mbus_frame_desc *fd);
-
 /**
  * v4l2_subdev_get_frame_desc_passthrough_dvp() - Helper to implement the subdev
  *	get_frame_desc operation in simple passthrough cases for DVP
-- 
2.47.3


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

* [PATCH v3 15/29] media: v4l2-subdev: Return dynamically allocated pass-through routes
  2026-08-24 12:14 [PATCH v3 00/29] Rework frame descriptors Sakari Ailus
                   ` (13 preceding siblings ...)
  2026-08-24 12:14 ` [PATCH v3 14/29] media: v4l2-subdev: Make v4l2_subdev_get_frame_desc_passthrough() static Sakari Ailus
@ 2026-08-24 12:14 ` Sakari Ailus
  2026-08-24 21:00   ` Frank Li
  2026-08-24 12:14 ` [PATCH v3 16/29] media: v4l2-subdev: Always return at least one frame descriptor Sakari Ailus
                   ` (14 subsequent siblings)
  29 siblings, 1 reply; 67+ messages in thread
From: Sakari Ailus @ 2026-08-24 12:14 UTC (permalink / raw)
  To: linux-media
  Cc: laurent.pinchart, Dave Stevenson, Jacopo Mondi, Tomi Valkeinen,
	Jai Luthra, Mehdi Djait, Mattijs Korpershoek

Count the number of pass-through routes, allocate memory and then return
the full table to the caller.

Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
---
 drivers/media/v4l2-core/v4l2-subdev.c | 61 +++++++++++++++++++++++----
 1 file changed, 52 insertions(+), 9 deletions(-)

diff --git a/drivers/media/v4l2-core/v4l2-subdev.c b/drivers/media/v4l2-core/v4l2-subdev.c
index c9f38b0313eb..d34704aad88e 100644
--- a/drivers/media/v4l2-core/v4l2-subdev.c
+++ b/drivers/media/v4l2-core/v4l2-subdev.c
@@ -2561,13 +2561,42 @@ int __v4l2_subdev_get_frame_desc_passthrough(struct v4l2_subdev *sd,
 	struct media_pad *local_sink_pad;
 	struct v4l2_subdev_route *route;
 	struct device *dev = sd->dev;
-	int ret = 0;
+	unsigned int num_entries = 0;
+	int ret;
 
 	lockdep_assert_held(state->lock);
 
 	if (WARN_ON(!(sd->entity.pads[pad].flags & MEDIA_PAD_FL_SOURCE)))
 		return -EINVAL;
 
+	/* Count the number of entries first */
+	media_entity_for_each_pad(&sd->entity, local_sink_pad) {
+		if (!(local_sink_pad->flags & MEDIA_PAD_FL_SINK))
+			continue;
+
+		for_each_active_route(&state->routing, route) {
+			if (route->source_pad != pad ||
+			    route->sink_pad != local_sink_pad->index)
+				continue;
+
+			num_entries++;
+
+			if (num_entries > V4L2_FRAME_DESC_ENTRY_MAX)
+				return -E2BIG;
+		}
+	}
+
+	if (num_entries > V4L2_FRAME_DESC_ENTRY_MAX)
+		return -E2BIG;
+
+	if (num_entries > V4L2_FRAME_DESC_ENTRY_PREALLOC) {
+		fd->entry = kzalloc_objs(*fd->entry, num_entries, GFP_KERNEL);
+		if (!fd->entry)
+			return -ENOMEM;
+
+		fd->len_entries = num_entries;
+	}
+
 	/* Iterate over sink pads */
 	media_entity_for_each_pad(&sd->entity, local_sink_pad) {
 		struct v4l2_mbus_frame_desc source_fd;
@@ -2594,12 +2623,15 @@ int __v4l2_subdev_get_frame_desc_passthrough(struct v4l2_subdev *sd,
 				if (IS_ERR(remote_source_pad)) {
 					dev_dbg(dev, "Failed to find remote pad for sink pad %u\n",
 						local_sink_pad->index);
-					return PTR_ERR(remote_source_pad);
+					ret = PTR_ERR(remote_source_pad);
+					goto err_free;
 				}
 
 				remote_sd = media_entity_to_v4l2_subdev(remote_source_pad->entity);
-				if (!remote_sd)
-					return -EINVAL;
+				if (!remote_sd) {
+					ret = -EINVAL;
+					goto err_free;
+				}
 
 				ret = v4l2_subdev_call(remote_sd, pad,
 						       get_frame_desc,
@@ -2609,7 +2641,7 @@ int __v4l2_subdev_get_frame_desc_passthrough(struct v4l2_subdev *sd,
 					dev_err(dev,
 						"Failed to get frame desc from remote subdev %s\n",
 						remote_sd->name);
-					return ret;
+					goto err_free;
 				}
 
 				have_source_fd = true;
@@ -2620,7 +2652,8 @@ int __v4l2_subdev_get_frame_desc_passthrough(struct v4l2_subdev *sd,
 					dev_err(dev,
 						"Frame desc type mismatch: %u != %u\n",
 						fd->type, source_fd.type);
-					return -EPIPE;
+					ret = -EPIPE;
+					goto err_free;
 				}
 			}
 
@@ -2635,12 +2668,14 @@ int __v4l2_subdev_get_frame_desc_passthrough(struct v4l2_subdev *sd,
 				dev_dbg(dev,
 					"Failed to find stream %u from source frame desc\n",
 					route->sink_stream);
-				return -EPIPE;
+				ret = -EPIPE;
+				goto err_free;
 			}
 
-			if (fd->num_entries >= V4L2_FRAME_DESC_ENTRY_PREALLOC) {
+			if (fd->num_entries >= fd->len_entries) {
 				dev_dbg(dev, "Frame desc entry limit reached\n");
-				return -E2BIG;
+				ret = -E2BIG;
+				goto err_free;
 			}
 
 			fd->entry[fd->num_entries] = *source_entry;
@@ -2652,6 +2687,14 @@ int __v4l2_subdev_get_frame_desc_passthrough(struct v4l2_subdev *sd,
 	}
 
 	return 0;
+
+err_free:
+	kfree(fd->entry);
+	fd->entry = fd->entry_mem;
+	fd->num_entries = 0;
+	fd->len_entries = V4L2_FRAME_DESC_ENTRY_PREALLOC;
+
+	return ret;
 }
 EXPORT_SYMBOL_GPL(__v4l2_subdev_get_frame_desc_passthrough);
 
-- 
2.47.3


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

* [PATCH v3 16/29] media: v4l2-subdev: Always return at least one frame descriptor
  2026-08-24 12:14 [PATCH v3 00/29] Rework frame descriptors Sakari Ailus
                   ` (14 preceding siblings ...)
  2026-08-24 12:14 ` [PATCH v3 15/29] media: v4l2-subdev: Return dynamically allocated pass-through routes Sakari Ailus
@ 2026-08-24 12:14 ` Sakari Ailus
  2026-08-24 12:14 ` [PATCH v3 17/29] media: bcm2835-unicam: Use v4l2_subdev_get_frame_desc() Sakari Ailus
                   ` (13 subsequent siblings)
  29 siblings, 0 replies; 67+ messages in thread
From: Sakari Ailus @ 2026-08-24 12:14 UTC (permalink / raw)
  To: linux-media
  Cc: laurent.pinchart, Dave Stevenson, Jacopo Mondi, Tomi Valkeinen,
	Jai Luthra, Mehdi Djait, Mattijs Korpershoek

Make v4l2_subdev_get_frame_desc() return at least one frame descriptor
entry or an error. Empty frame descriptors aren't useful for callers so
callers can now omit this check.

Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
Reviewed-by: Frank Li <Frank.Li@nxp.com>
---
 drivers/media/v4l2-core/v4l2-subdev.c | 6 ++++++
 include/media/v4l2-subdev.h           | 2 ++
 2 files changed, 8 insertions(+)

diff --git a/drivers/media/v4l2-core/v4l2-subdev.c b/drivers/media/v4l2-core/v4l2-subdev.c
index d34704aad88e..8c3c5b6e4ee8 100644
--- a/drivers/media/v4l2-core/v4l2-subdev.c
+++ b/drivers/media/v4l2-core/v4l2-subdev.c
@@ -2774,6 +2774,12 @@ v4l2_subdev_get_frame_desc(struct v4l2_subdev *sd, unsigned int pad,
 			goto err_free;
 		}
 
+		if (!desc->num_entries) {
+			dev_dbg(sd->dev, "no frame descriptor entries\n");
+			ret = -EINVAL;
+			goto err_free;
+		}
+
 		return desc;
 	}
 
diff --git a/include/media/v4l2-subdev.h b/include/media/v4l2-subdev.h
index cfe285f44f57..516473758761 100644
--- a/include/media/v4l2-subdev.h
+++ b/include/media/v4l2-subdev.h
@@ -1847,6 +1847,8 @@ int v4l2_subdev_get_frame_desc_passthrough_csi2(struct v4l2_subdev *sd,
  *    struct v4l2_mbus_frame_desc *desc __free(v4l2_subdev_free_frame_desc) =
  *            v4l2_subdev_get_frame_desc(sd, pad, desc);
  *
+ * The returned frame descriptor will contain at least one entry.
+ *
  * Return: The frame descriptor on success or a negative error code on failure.
  */
 struct v4l2_mbus_frame_desc *
-- 
2.47.3


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

* [PATCH v3 17/29] media: bcm2835-unicam: Use v4l2_subdev_get_frame_desc()
  2026-08-24 12:14 [PATCH v3 00/29] Rework frame descriptors Sakari Ailus
                   ` (15 preceding siblings ...)
  2026-08-24 12:14 ` [PATCH v3 16/29] media: v4l2-subdev: Always return at least one frame descriptor Sakari Ailus
@ 2026-08-24 12:14 ` Sakari Ailus
  2026-08-24 21:07   ` Frank Li
  2026-08-24 12:14 ` [PATCH v3 18/29] media: bcm2835-unicam: Remove frame descriptor workaround Sakari Ailus
                   ` (12 subsequent siblings)
  29 siblings, 1 reply; 67+ messages in thread
From: Sakari Ailus @ 2026-08-24 12:14 UTC (permalink / raw)
  To: linux-media
  Cc: laurent.pinchart, Dave Stevenson, Jacopo Mondi, Tomi Valkeinen,
	Jai Luthra, Mehdi Djait, Mattijs Korpershoek

Call v4l2_subdev_get_frame_desc() to obtain the frame descriptor. This is
preferred over calling the get_frame_desc() pad operation directly.

Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
---
 .../media/platform/broadcom/bcm2835-unicam.c  | 22 +++++++++----------
 1 file changed, 10 insertions(+), 12 deletions(-)

diff --git a/drivers/media/platform/broadcom/bcm2835-unicam.c b/drivers/media/platform/broadcom/bcm2835-unicam.c
index 14bb916dd7b1..2322d3df3915 100644
--- a/drivers/media/platform/broadcom/bcm2835-unicam.c
+++ b/drivers/media/platform/broadcom/bcm2835-unicam.c
@@ -27,6 +27,7 @@
  * output interface and V4L2 subdevice driver.
  */
 
+#include <linux/cleanup.h>
 #include <linux/clk.h>
 #include <linux/delay.h>
 #include <linux/device.h>
@@ -888,7 +889,6 @@ static int unicam_get_image_vc_dt(struct unicam_device *unicam,
 				  struct v4l2_subdev_state *state,
 				  u8 *vc, u8 *dt)
 {
-	struct v4l2_mbus_frame_desc fd;
 	u32 stream;
 	int ret;
 
@@ -898,17 +898,15 @@ static int unicam_get_image_vc_dt(struct unicam_device *unicam,
 	if (ret)
 		return ret;
 
-	ret = v4l2_subdev_call(unicam->sensor.subdev, pad, get_frame_desc,
-			       unicam->sensor.pad->index, &fd);
-	if (ret)
-		return ret;
-
-	/* Only CSI-2 supports DTs. */
-	if (fd.type != V4L2_MBUS_FRAME_DESC_TYPE_CSI2)
-		return -EINVAL;
+	struct v4l2_mbus_frame_desc *fd __free(v4l2_subdev_free_frame_desc) =
+		v4l2_subdev_get_frame_desc(unicam->sensor.subdev,
+					   unicam->sensor.pad->index,
+					   V4L2_MBUS_FRAME_DESC_TYPE_CSI2);
+	if (IS_ERR(fd))
+		return PTR_ERR(fd);
 
-	for (unsigned int i = 0; i < fd.num_entries; ++i) {
-		const struct v4l2_mbus_frame_desc_entry *fde = &fd.entry[i];
+	for (unsigned int i = 0; i < fd->num_entries; ++i) {
+		const struct v4l2_mbus_frame_desc_entry *fde = &fd->entry[i];
 
 		if (fde->stream == stream) {
 			*vc = fde->bus.csi2.vc;
@@ -927,7 +925,7 @@ static void unicam_start_rx(struct unicam_device *unicam,
 	const struct unicam_format_info *fmtinfo;
 	const struct v4l2_mbus_framefmt *fmt;
 	unsigned int line_int_freq;
-	u8 vc, dt;
+	u8 vc = 0, dt = 0;
 	u32 val;
 	int ret;
 
-- 
2.47.3


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

* [PATCH v3 18/29] media: bcm2835-unicam: Remove frame descriptor workaround
  2026-08-24 12:14 [PATCH v3 00/29] Rework frame descriptors Sakari Ailus
                   ` (16 preceding siblings ...)
  2026-08-24 12:14 ` [PATCH v3 17/29] media: bcm2835-unicam: Use v4l2_subdev_get_frame_desc() Sakari Ailus
@ 2026-08-24 12:14 ` Sakari Ailus
  2026-08-24 21:10   ` Frank Li
  2026-08-24 12:14 ` [PATCH v3 19/29] media: nxp: imx8-isi: Use v4l2_subdev_get_frame_desc() Sakari Ailus
                   ` (11 subsequent siblings)
  29 siblings, 1 reply; 67+ messages in thread
From: Sakari Ailus @ 2026-08-24 12:14 UTC (permalink / raw)
  To: linux-media
  Cc: laurent.pinchart, Dave Stevenson, Jacopo Mondi, Tomi Valkeinen,
	Jai Luthra, Mehdi Djait, Mattijs Korpershoek

As the v4l2_subdev_get_frame_desc() either returns a frame descriptor or
returns an error, remove the workaround for drivers that didn't implement
the get_frame_desc() pad op. Also handle v4l2_subdev_get_frame_desc()
errors.

Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
---
 .../media/platform/broadcom/bcm2835-unicam.c  | 26 +++++++++----------
 1 file changed, 12 insertions(+), 14 deletions(-)

diff --git a/drivers/media/platform/broadcom/bcm2835-unicam.c b/drivers/media/platform/broadcom/bcm2835-unicam.c
index 2322d3df3915..ba613966c333 100644
--- a/drivers/media/platform/broadcom/bcm2835-unicam.c
+++ b/drivers/media/platform/broadcom/bcm2835-unicam.c
@@ -918,8 +918,8 @@ static int unicam_get_image_vc_dt(struct unicam_device *unicam,
 	return -EINVAL;
 }
 
-static void unicam_start_rx(struct unicam_device *unicam,
-			    struct v4l2_subdev_state *state)
+static int unicam_start_rx(struct unicam_device *unicam,
+			   struct v4l2_subdev_state *state)
 {
 	struct unicam_node *node = &unicam->node[UNICAM_IMAGE_NODE];
 	const struct unicam_format_info *fmtinfo;
@@ -933,7 +933,11 @@ static void unicam_start_rx(struct unicam_device *unicam,
 	fmtinfo = unicam_find_format_by_code(fmt->code,
 					     UNICAM_SD_PAD_SOURCE_IMAGE);
 	if (WARN_ON(!fmtinfo))
-		return;
+		return -EINVAL;
+
+	ret = unicam_get_image_vc_dt(unicam, state, &vc, &dt);
+	if (ret)
+		return ret;
 
 	/*
 	 * Enable lane clocks. The register is structured as follows:
@@ -1090,16 +1094,6 @@ static void unicam_start_rx(struct unicam_device *unicam,
 	unicam_wr_dma_addr(node, node->cur_frm);
 	unicam_set_packing_config(unicam, fmtinfo);
 
-	ret = unicam_get_image_vc_dt(unicam, state, &vc, &dt);
-	if (ret) {
-		/*
-		 * If the source doesn't support frame descriptors, default to
-		 * VC 0 and use the DT corresponding to the format.
-		 */
-		vc = 0;
-		dt = fmtinfo->csi_dt;
-	}
-
 	unicam_cfg_image_id(unicam, vc, dt);
 
 	val = unicam_reg_read(unicam, UNICAM_MISC);
@@ -1118,6 +1112,8 @@ static void unicam_start_rx(struct unicam_device *unicam,
 	 * sync correctly to the FS from the source.
 	 */
 	unicam_reg_write_field(unicam, UNICAM_ICTL, 1, UNICAM_TFC);
+
+	return 0;
 }
 
 static void unicam_start_metadata(struct unicam_device *unicam)
@@ -1427,7 +1423,9 @@ static int unicam_sd_enable_streams(struct v4l2_subdev *sd,
 			unicam_start_metadata(unicam);
 
 		unicam->frame_started = false;
-		unicam_start_rx(unicam, state);
+		ret = unicam_start_rx(unicam, state);
+		if (ret)
+			return ret;
 	}
 
 	ret = v4l2_subdev_routing_find_opposite_end(&state->routing, pad, 0,
-- 
2.47.3


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

* [PATCH v3 19/29] media: nxp: imx8-isi: Use v4l2_subdev_get_frame_desc()
  2026-08-24 12:14 [PATCH v3 00/29] Rework frame descriptors Sakari Ailus
                   ` (17 preceding siblings ...)
  2026-08-24 12:14 ` [PATCH v3 18/29] media: bcm2835-unicam: Remove frame descriptor workaround Sakari Ailus
@ 2026-08-24 12:14 ` Sakari Ailus
  2026-08-24 12:14 ` [PATCH v3 20/29] media: raspberrypi: cfe: " Sakari Ailus
                   ` (10 subsequent siblings)
  29 siblings, 0 replies; 67+ messages in thread
From: Sakari Ailus @ 2026-08-24 12:14 UTC (permalink / raw)
  To: linux-media
  Cc: laurent.pinchart, Dave Stevenson, Jacopo Mondi, Tomi Valkeinen,
	Jai Luthra, Mehdi Djait, Mattijs Korpershoek

Call v4l2_subdev_get_frame_desc() to obtain the frame descriptor. This is
preferred over calling the get_frame_desc() pad operation directly.

Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
Reviewed-by: Frank Li <Frank.Li@nxp.com>
---
 .../platform/nxp/imx8-isi/imx8-isi-crossbar.c | 19 +++++++--------
 .../platform/nxp/imx8-isi/imx8-isi-pipe.c     | 23 +++++++++----------
 2 files changed, 21 insertions(+), 21 deletions(-)

diff --git a/drivers/media/platform/nxp/imx8-isi/imx8-isi-crossbar.c b/drivers/media/platform/nxp/imx8-isi/imx8-isi-crossbar.c
index e6c38a769205..5aef5cd179cf 100644
--- a/drivers/media/platform/nxp/imx8-isi/imx8-isi-crossbar.c
+++ b/drivers/media/platform/nxp/imx8-isi/imx8-isi-crossbar.c
@@ -5,6 +5,7 @@
  * Copyright (c) 2022 Laurent Pinchart <laurent.pinchart@ideasonboard.com>
  */
 
+#include <linux/cleanup.h>
 #include <linux/device.h>
 #include <linux/errno.h>
 #include <linux/kernel.h>
@@ -32,8 +33,6 @@ static int mxc_isi_crossbar_gasket_enable(struct mxc_isi_crossbar *xbar,
 	struct mxc_isi_dev *isi = xbar->isi;
 	const struct mxc_gasket_ops *gasket_ops = isi->pdata->gasket_ops;
 	const struct v4l2_mbus_framefmt *fmt;
-	struct v4l2_mbus_frame_desc fd;
-	int ret;
 
 	if (!gasket_ops)
 		return 0;
@@ -44,15 +43,17 @@ static int mxc_isi_crossbar_gasket_enable(struct mxc_isi_crossbar *xbar,
 	 * to match the configuration of the CSIS.
 	 */
 
-	ret = v4l2_subdev_call(remote_sd, pad, get_frame_desc, remote_pad, &fd);
-	if (ret) {
+	struct v4l2_mbus_frame_desc *fd __free(v4l2_subdev_free_frame_desc) =
+		v4l2_subdev_get_frame_desc(remote_sd, remote_pad,
+					   V4L2_MBUS_FRAME_DESC_TYPE_PARALLEL);
+	if (IS_ERR(fd)) {
 		dev_err(isi->dev,
-			"failed to get frame descriptor from '%s':%u: %d\n",
-			remote_sd->name, remote_pad, ret);
-		return ret;
+			"failed to get frame descriptor from '%s':%u: %pe\n",
+			remote_sd->name, remote_pad, fd);
+		return PTR_ERR(fd);
 	}
 
-	if (fd.num_entries != 1) {
+	if (fd->num_entries != 1) {
 		dev_err(isi->dev, "invalid frame descriptor for '%s':%u\n",
 			remote_sd->name, remote_pad);
 		return -EINVAL;
@@ -62,7 +63,7 @@ static int mxc_isi_crossbar_gasket_enable(struct mxc_isi_crossbar *xbar,
 	if (!fmt)
 		return -EINVAL;
 
-	gasket_ops->enable(isi, &fd, fmt, port);
+	gasket_ops->enable(isi, fd, fmt, port);
 	return 0;
 }
 
diff --git a/drivers/media/platform/nxp/imx8-isi/imx8-isi-pipe.c b/drivers/media/platform/nxp/imx8-isi/imx8-isi-pipe.c
index 934f7b356258..12b296d7bbe0 100644
--- a/drivers/media/platform/nxp/imx8-isi/imx8-isi-pipe.c
+++ b/drivers/media/platform/nxp/imx8-isi/imx8-isi-pipe.c
@@ -266,27 +266,26 @@ static int mxc_isi_get_vc(struct mxc_isi_pipe *pipe)
 {
 	struct mxc_isi_crossbar *xbar = &pipe->isi->crossbar;
 	struct device *dev = pipe->isi->dev;
-	struct v4l2_mbus_frame_desc fd = { };
 	unsigned int source_pad = xbar->num_sinks + pipe->id;
 	unsigned int num_vcs;
 	unsigned int i;
-	int ret;
 
-	ret = v4l2_subdev_call(&xbar->sd, pad, get_frame_desc,
-			       source_pad, &fd);
-	if (ret < 0) {
+	struct v4l2_mbus_frame_desc *fd __free(v4l2_subdev_free_frame_desc) =
+		v4l2_subdev_get_frame_desc(&xbar->sd, source_pad,
+					   V4L2_MBUS_FRAME_DESC_TYPE_CSI2);
+	if (IS_ERR(fd)) {
 		dev_err(dev, "Failed to get source frame desc from pad %u\n",
 			source_pad);
-		return ret;
+		return PTR_ERR(fd);
 	}
 
 	/* Find stream 0 in the frame descriptor. */
-	for (i = 0; i < fd.num_entries; i++) {
-		if (fd.entry[i].stream == 0)
+	for (i = 0; i < fd->num_entries; i++) {
+		if (fd->entry[i].stream == 0)
 			break;
 	}
 
-	if (i == fd.num_entries) {
+	if (i == fd->num_entries) {
 		dev_err(dev, "Failed to find stream from source frame desc\n");
 		return -EPIPE;
 	}
@@ -294,13 +293,13 @@ static int mxc_isi_get_vc(struct mxc_isi_pipe *pipe)
 	num_vcs = pipe->isi->pdata->num_vc ? : 1;
 
 	/* Check virtual channel range. */
-	if (fd.entry[i].bus.csi2.vc >= num_vcs) {
+	if (fd->entry[i].bus.csi2.vc >= num_vcs) {
 		dev_err(dev, "Virtual channel %u exceeds maximum %u\n",
-			fd.entry[i].bus.csi2.vc, num_vcs - 1);
+			fd->entry[i].bus.csi2.vc, num_vcs - 1);
 		return -EPIPE;
 	}
 
-	return fd.entry[i].bus.csi2.vc;
+	return fd->entry[i].bus.csi2.vc;
 }
 
 int mxc_isi_pipe_enable(struct mxc_isi_pipe *pipe)
-- 
2.47.3


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

* [PATCH v3 20/29] media: raspberrypi: cfe: Use v4l2_subdev_get_frame_desc()
  2026-08-24 12:14 [PATCH v3 00/29] Rework frame descriptors Sakari Ailus
                   ` (18 preceding siblings ...)
  2026-08-24 12:14 ` [PATCH v3 19/29] media: nxp: imx8-isi: Use v4l2_subdev_get_frame_desc() Sakari Ailus
@ 2026-08-24 12:14 ` Sakari Ailus
  2026-08-24 21:11   ` Frank Li
  2026-08-24 12:14 ` [PATCH v3 21/29] media: rzg2l-cru: " Sakari Ailus
                   ` (9 subsequent siblings)
  29 siblings, 1 reply; 67+ messages in thread
From: Sakari Ailus @ 2026-08-24 12:14 UTC (permalink / raw)
  To: linux-media
  Cc: laurent.pinchart, Dave Stevenson, Jacopo Mondi, Tomi Valkeinen,
	Jai Luthra, Mehdi Djait, Mattijs Korpershoek

Call v4l2_subdev_get_frame_desc() to obtain the frame descriptor. This is
preferred over calling the get_frame_desc() pad operation directly. Also
remove the workaround for drivers not implementing the get_frame_desc()
pad op.

Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
---
 .../media/platform/raspberrypi/rp1-cfe/cfe.c  | 51 ++++---------------
 1 file changed, 11 insertions(+), 40 deletions(-)

diff --git a/drivers/media/platform/raspberrypi/rp1-cfe/cfe.c b/drivers/media/platform/raspberrypi/rp1-cfe/cfe.c
index 8375ed3e97b9..e99a77e0878e 100644
--- a/drivers/media/platform/raspberrypi/rp1-cfe/cfe.c
+++ b/drivers/media/platform/raspberrypi/rp1-cfe/cfe.c
@@ -6,6 +6,7 @@
  * Copyright (c) 2023-2024 Ideas on Board Oy
  */
 
+#include <linux/cleanup.h>
 #include <linux/clk.h>
 #include <linux/debugfs.h>
 #include <linux/delay.h>
@@ -778,32 +779,9 @@ static irqreturn_t cfe_isr(int irq, void *dev)
  * Stream helpers
  */
 
-static int cfe_get_vc_dt_fallback(struct cfe_device *cfe, u8 *vc, u8 *dt)
-{
-	struct v4l2_subdev_state *state;
-	struct v4l2_mbus_framefmt *fmt;
-	const struct cfe_fmt *cfe_fmt;
-
-	state = v4l2_subdev_get_locked_active_state(&cfe->csi2.sd);
-
-	fmt = v4l2_subdev_state_get_format(state, CSI2_PAD_SINK, 0);
-	if (!fmt)
-		return -EINVAL;
-
-	cfe_fmt = find_format_by_code(fmt->code);
-	if (!cfe_fmt)
-		return -EINVAL;
-
-	*vc = 0;
-	*dt = cfe_fmt->csi_dt;
-
-	return 0;
-}
-
 static int cfe_get_vc_dt(struct cfe_device *cfe, unsigned int channel, u8 *vc,
 			 u8 *dt)
 {
-	struct v4l2_mbus_frame_desc remote_desc;
 	struct v4l2_subdev_state *state;
 	u32 sink_stream;
 	unsigned int i;
@@ -816,34 +794,27 @@ static int cfe_get_vc_dt(struct cfe_device *cfe, unsigned int channel, u8 *vc,
 	if (ret)
 		return ret;
 
-	ret = v4l2_subdev_call(cfe->source_sd, pad, get_frame_desc,
-			       cfe->source_pad, &remote_desc);
-	if (ret == -ENOIOCTLCMD) {
-		cfe_dbg(cfe, "source does not support get_frame_desc, use fallback\n");
-		return cfe_get_vc_dt_fallback(cfe, vc, dt);
-	} else if (ret) {
+	struct v4l2_mbus_frame_desc *fd __free(v4l2_subdev_free_frame_desc) =
+		v4l2_subdev_get_frame_desc(cfe->source_sd, cfe->source_pad,
+					   V4L2_MBUS_FRAME_DESC_TYPE_CSI2);
+	if (IS_ERR(fd)) {
 		cfe_err(cfe, "Failed to get frame descriptor\n");
-		return ret;
-	}
-
-	if (remote_desc.type != V4L2_MBUS_FRAME_DESC_TYPE_CSI2) {
-		cfe_err(cfe, "Frame descriptor does not describe CSI-2 link");
-		return -EINVAL;
+		return PTR_ERR(fd);
 	}
 
-	for (i = 0; i < remote_desc.num_entries; i++) {
-		if (remote_desc.entry[i].stream == sink_stream)
+	for (i = 0; i < fd->num_entries; i++) {
+		if (fd->entry[i].stream == sink_stream)
 			break;
 	}
 
-	if (i == remote_desc.num_entries) {
+	if (i == fd->num_entries) {
 		cfe_err(cfe, "Stream %u not found in remote frame desc\n",
 			sink_stream);
 		return -EINVAL;
 	}
 
-	*vc = remote_desc.entry[i].bus.csi2.vc;
-	*dt = remote_desc.entry[i].bus.csi2.dt;
+	*vc = fd->entry[i].bus.csi2.vc;
+	*dt = fd->entry[i].bus.csi2.dt;
 
 	return 0;
 }
-- 
2.47.3


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

* [PATCH v3 21/29] media: rzg2l-cru: Use v4l2_subdev_get_frame_desc()
  2026-08-24 12:14 [PATCH v3 00/29] Rework frame descriptors Sakari Ailus
                   ` (19 preceding siblings ...)
  2026-08-24 12:14 ` [PATCH v3 20/29] media: raspberrypi: cfe: " Sakari Ailus
@ 2026-08-24 12:14 ` Sakari Ailus
  2026-08-24 21:13   ` Frank Li
  2026-08-24 12:14 ` [PATCH v3 22/29] media: rkisp1: " Sakari Ailus
                   ` (8 subsequent siblings)
  29 siblings, 1 reply; 67+ messages in thread
From: Sakari Ailus @ 2026-08-24 12:14 UTC (permalink / raw)
  To: linux-media
  Cc: laurent.pinchart, Dave Stevenson, Jacopo Mondi, Tomi Valkeinen,
	Jai Luthra, Mehdi Djait, Mattijs Korpershoek

Call v4l2_subdev_get_frame_desc() to obtain the frame descriptor. This is
preferred over calling the get_frame_desc() pad operation directly.

Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
---
 .../platform/renesas/rzg2l-cru/rzg2l-video.c  | 27 +++++--------------
 1 file changed, 7 insertions(+), 20 deletions(-)

diff --git a/drivers/media/platform/renesas/rzg2l-cru/rzg2l-video.c b/drivers/media/platform/renesas/rzg2l-cru/rzg2l-video.c
index 91eda5034248..90c074527e01 100644
--- a/drivers/media/platform/renesas/rzg2l-cru/rzg2l-video.c
+++ b/drivers/media/platform/renesas/rzg2l-cru/rzg2l-video.c
@@ -11,6 +11,7 @@
  * Copyright (C) 2008 Magnus Damm
  */
 
+#include <linux/cleanup.h>
 #include <linux/clk.h>
 #include <linux/delay.h>
 #include <linux/pm_runtime.h>
@@ -438,31 +439,17 @@ void rzg2l_cru_stop_image_processing(struct rzg2l_cru_dev *cru)
 
 static int rzg2l_cru_get_virtual_channel(struct rzg2l_cru_dev *cru)
 {
-	struct v4l2_mbus_frame_desc fd = { };
 	struct media_pad *remote_pad;
-	int ret;
 
 	remote_pad = media_pad_remote_pad_unique(&cru->ip.pads[RZG2L_CRU_IP_SINK]);
-	ret = v4l2_subdev_call(cru->ip.remote, pad, get_frame_desc, remote_pad->index, &fd);
-	if (ret < 0 && ret != -ENOIOCTLCMD) {
-		dev_err(cru->dev, "get_frame_desc failed on IP remote subdev\n");
-		return ret;
-	}
-	/* If remote subdev does not implement .get_frame_desc default to VC0. */
-	if (ret == -ENOIOCTLCMD)
-		return 0;
 
-	if (fd.type != V4L2_MBUS_FRAME_DESC_TYPE_CSI2) {
-		dev_err(cru->dev, "get_frame_desc returned invalid bus type %d\n", fd.type);
-		return -EINVAL;
-	}
-
-	if (!fd.num_entries) {
-		dev_err(cru->dev, "get_frame_desc returned zero entries\n");
-		return -EINVAL;
-	}
+	struct v4l2_mbus_frame_desc *fd __free(v4l2_subdev_free_frame_desc) =
+		v4l2_subdev_get_frame_desc(cru->ip.remote, remote_pad->index,
+					   V4L2_MBUS_FRAME_DESC_TYPE_CSI2);
+	if (IS_ERR(fd))
+		return PTR_ERR(fd);
 
-	return fd.entry[0].bus.csi2.vc;
+	return fd->entry[0].bus.csi2.vc;
 }
 
 void rzg3e_cru_enable_interrupts(struct rzg2l_cru_dev *cru)
-- 
2.47.3


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

* [PATCH v3 22/29] media: rkisp1: Use v4l2_subdev_get_frame_desc()
  2026-08-24 12:14 [PATCH v3 00/29] Rework frame descriptors Sakari Ailus
                   ` (20 preceding siblings ...)
  2026-08-24 12:14 ` [PATCH v3 21/29] media: rzg2l-cru: " Sakari Ailus
@ 2026-08-24 12:14 ` Sakari Ailus
  2026-08-24 21:13   ` Frank Li
  2026-08-24 12:14 ` [PATCH v3 23/29] media: exynos4-is: " Sakari Ailus
                   ` (7 subsequent siblings)
  29 siblings, 1 reply; 67+ messages in thread
From: Sakari Ailus @ 2026-08-24 12:14 UTC (permalink / raw)
  To: linux-media
  Cc: laurent.pinchart, Dave Stevenson, Jacopo Mondi, Tomi Valkeinen,
	Jai Luthra, Mehdi Djait, Mattijs Korpershoek

Call v4l2_subdev_get_frame_desc() to obtain the frame descriptor. This is
preferred over calling the get_frame_desc() pad operation directly.

Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
---
 .../platform/rockchip/rkisp1/rkisp1-isp.c     | 21 ++++++++++---------
 1 file changed, 11 insertions(+), 10 deletions(-)

diff --git a/drivers/media/platform/rockchip/rkisp1/rkisp1-isp.c b/drivers/media/platform/rockchip/rkisp1/rkisp1-isp.c
index 2311672cedb1..eb8e881759f7 100644
--- a/drivers/media/platform/rockchip/rkisp1/rkisp1-isp.c
+++ b/drivers/media/platform/rockchip/rkisp1/rkisp1-isp.c
@@ -8,6 +8,7 @@
  * Copyright (C) 2017 Rockchip Electronics Co., Ltd.
  */
 
+#include <linux/cleanup.h>
 #include <linux/iopoll.h>
 #include <linux/pm_runtime.h>
 #include <linux/regmap.h>
@@ -87,11 +88,9 @@ static int rkisp1_gasket_enable(struct rkisp1_device *rkisp1,
 				struct media_pad *source)
 {
 	struct v4l2_subdev *source_sd;
-	struct v4l2_mbus_frame_desc fd;
 	unsigned int dt;
 	u32 mask;
 	u32 val;
-	int ret;
 
 	/*
 	 * Configure and enable the gasket with the CSI-2 data type. Set the
@@ -101,22 +100,24 @@ static int rkisp1_gasket_enable(struct rkisp1_device *rkisp1,
 	 */
 
 	source_sd = media_entity_to_v4l2_subdev(source->entity);
-	ret = v4l2_subdev_call(source_sd, pad, get_frame_desc,
-			       source->index, &fd);
-	if (ret) {
+
+	struct v4l2_mbus_frame_desc *fd __free(v4l2_subdev_free_frame_desc) =
+		v4l2_subdev_get_frame_desc(source_sd, source->index,
+					   V4L2_MBUS_FRAME_DESC_TYPE_CSI2);
+	if (IS_ERR(fd)) {
 		dev_err(rkisp1->dev,
-			"failed to get frame descriptor from '%s':%u: %d\n",
-			source_sd->name, 0, ret);
-		return ret;
+			"failed to get frame descriptor from '%s':%u: %pe\n",
+			source_sd->name, 0, fd);
+		return PTR_ERR(fd);
 	}
 
-	if (fd.num_entries != 1) {
+	if (fd->num_entries != 1) {
 		dev_err(rkisp1->dev, "invalid frame descriptor for '%s':%u\n",
 			source_sd->name, 0);
 		return -EINVAL;
 	}
 
-	dt = fd.entry[0].bus.csi2.dt;
+	dt = fd->entry[0].bus.csi2.dt;
 
 	if (rkisp1->gasket_id == 0) {
 		mask = ISP_DEWARP_CONTROL_MIPI_CSI1_HS_POLARITY
-- 
2.47.3


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

* [PATCH v3 23/29] media: exynos4-is: Use v4l2_subdev_get_frame_desc()
  2026-08-24 12:14 [PATCH v3 00/29] Rework frame descriptors Sakari Ailus
                   ` (21 preceding siblings ...)
  2026-08-24 12:14 ` [PATCH v3 22/29] media: rkisp1: " Sakari Ailus
@ 2026-08-24 12:14 ` Sakari Ailus
  2026-08-24 21:22   ` Frank Li
  2026-08-24 12:14 ` [PATCH v3 24/29] media: ti: cal: " Sakari Ailus
                   ` (6 subsequent siblings)
  29 siblings, 1 reply; 67+ messages in thread
From: Sakari Ailus @ 2026-08-24 12:14 UTC (permalink / raw)
  To: linux-media
  Cc: laurent.pinchart, Dave Stevenson, Jacopo Mondi, Tomi Valkeinen,
	Jai Luthra, Mehdi Djait, Mattijs Korpershoek

Call v4l2_subdev_get_frame_desc() to obtain the frame descriptor. This is
preferred over calling the get_frame_desc() pad operation directly.

Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
---
 .../platform/samsung/exynos4-is/fimc-capture.c | 18 ++++++++++++++----
 1 file changed, 14 insertions(+), 4 deletions(-)

diff --git a/drivers/media/platform/samsung/exynos4-is/fimc-capture.c b/drivers/media/platform/samsung/exynos4-is/fimc-capture.c
index d85811f4b8c5..b5749f9cba39 100644
--- a/drivers/media/platform/samsung/exynos4-is/fimc-capture.c
+++ b/drivers/media/platform/samsung/exynos4-is/fimc-capture.c
@@ -6,6 +6,7 @@
  * Sylwester Nawrocki <s.nawrocki@samsung.com>
  */
 
+#include <linux/cleanup.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/types.h>
@@ -853,7 +854,8 @@ static int fimc_get_sensor_frame_desc(struct v4l2_subdev *sensor,
 				      struct v4l2_plane_pix_format *plane_fmt,
 				      unsigned int num_planes, bool try)
 {
-	struct v4l2_mbus_frame_desc fd = { };
+	struct v4l2_mbus_frame_desc *alloc_fd
+		__free(v4l2_subdev_free_frame_desc) = NULL, fd = { };
 	int i, ret;
 	int pad;
 
@@ -861,10 +863,18 @@ static int fimc_get_sensor_frame_desc(struct v4l2_subdev *sensor,
 		fd.entry[i].length = plane_fmt[i].sizeimage;
 
 	pad = sensor->entity.num_pads - 1;
-	if (try)
+	if (try) {
 		ret = v4l2_subdev_call(sensor, pad, set_frame_desc, pad, &fd);
-	else
-		ret = v4l2_subdev_call(sensor, pad, get_frame_desc, pad, &fd);
+	} else {
+		alloc_fd = v4l2_subdev_get_frame_desc(sensor, pad,
+						      V4L2_MBUS_FRAME_DESC_TYPE_CSI2);
+		if (IS_ERR(alloc_fd)) {
+			ret = PTR_ERR(alloc_fd);
+		} else {
+			fd = *alloc_fd;
+			ret = 0;
+		}
+	}
 
 	if (ret < 0)
 		return ret;
-- 
2.47.3


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

* [PATCH v3 24/29] media: ti: cal: Use v4l2_subdev_get_frame_desc()
  2026-08-24 12:14 [PATCH v3 00/29] Rework frame descriptors Sakari Ailus
                   ` (22 preceding siblings ...)
  2026-08-24 12:14 ` [PATCH v3 23/29] media: exynos4-is: " Sakari Ailus
@ 2026-08-24 12:14 ` Sakari Ailus
  2026-08-24 21:26   ` Frank Li
  2026-08-24 12:14 ` [PATCH v3 25/29] media: ipu6: " Sakari Ailus
                   ` (5 subsequent siblings)
  29 siblings, 1 reply; 67+ messages in thread
From: Sakari Ailus @ 2026-08-24 12:14 UTC (permalink / raw)
  To: linux-media
  Cc: laurent.pinchart, Dave Stevenson, Jacopo Mondi, Tomi Valkeinen,
	Jai Luthra, Mehdi Djait, Mattijs Korpershoek

Call v4l2_subdev_get_frame_desc() to obtain the frame descriptor. This is
preferred over calling the get_frame_desc() pad operation directly.

Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
---
 drivers/media/platform/ti/cal/cal-camerarx.c | 26 +++++------
 drivers/media/platform/ti/cal/cal.c          | 49 ++++++--------------
 2 files changed, 27 insertions(+), 48 deletions(-)

diff --git a/drivers/media/platform/ti/cal/cal-camerarx.c b/drivers/media/platform/ti/cal/cal-camerarx.c
index 00a71dac0ff4..9ea1f3551d22 100644
--- a/drivers/media/platform/ti/cal/cal-camerarx.c
+++ b/drivers/media/platform/ti/cal/cal-camerarx.c
@@ -9,6 +9,7 @@
  *	Laurent Pinchart <laurent.pinchart@ideasonboard.com>
  */
 
+#include <linux/cleanup.h>
 #include <linux/clk.h>
 #include <linux/delay.h>
 #include <linux/mfd/syscon.h>
@@ -872,7 +873,8 @@ static int cal_camerarx_get_frame_desc(struct v4l2_subdev *sd, unsigned int pad,
 				       struct v4l2_mbus_frame_desc *fd)
 {
 	struct cal_camerarx *phy = to_cal_camerarx(sd);
-	struct v4l2_mbus_frame_desc remote_desc;
+	struct v4l2_mbus_frame_desc *remote_desc
+		__free(v4l2_subdev_free_frame_desc) = NULL;
 	const struct media_pad *remote_pad;
 	struct v4l2_subdev_state *state;
 	u32 sink_stream;
@@ -893,24 +895,20 @@ static int cal_camerarx_get_frame_desc(struct v4l2_subdev *sd, unsigned int pad,
 		goto out_unlock;
 	}
 
-	ret = v4l2_subdev_call(phy->source, pad, get_frame_desc,
-			       remote_pad->index, &remote_desc);
-	if (ret)
-		goto out_unlock;
-
-	if (remote_desc.type != V4L2_MBUS_FRAME_DESC_TYPE_CSI2) {
-		cal_err(phy->cal,
-			"Frame descriptor does not describe CSI-2 link");
-		ret = -EINVAL;
+	remote_desc =
+		v4l2_subdev_get_frame_desc(phy->source, remote_pad->index,
+					   V4L2_MBUS_FRAME_DESC_TYPE_CSI2);
+	if (IS_ERR(remote_desc)) {
+		ret = PTR_ERR(remote_desc);
 		goto out_unlock;
 	}
 
-	for (i = 0; i < remote_desc.num_entries; i++) {
-		if (remote_desc.entry[i].stream == sink_stream)
+	for (i = 0; i < remote_desc->num_entries; i++) {
+		if (remote_desc->entry[i].stream == sink_stream)
 			break;
 	}
 
-	if (i == remote_desc.num_entries) {
+	if (i == remote_desc->num_entries) {
 		cal_err(phy->cal, "Stream %u not found in remote frame desc\n",
 			sink_stream);
 		ret = -EINVAL;
@@ -919,7 +917,7 @@ static int cal_camerarx_get_frame_desc(struct v4l2_subdev *sd, unsigned int pad,
 
 	fd->type = V4L2_MBUS_FRAME_DESC_TYPE_CSI2;
 	fd->num_entries = 1;
-	fd->entry[0] = remote_desc.entry[i];
+	fd->entry[0] = remote_desc->entry[i];
 
 out_unlock:
 	v4l2_subdev_unlock_state(state);
diff --git a/drivers/media/platform/ti/cal/cal.c b/drivers/media/platform/ti/cal/cal.c
index b7e77b6b8950..20192f90d5b3 100644
--- a/drivers/media/platform/ti/cal/cal.c
+++ b/drivers/media/platform/ti/cal/cal.c
@@ -445,55 +445,36 @@ static bool cal_ctx_wr_dma_stopped(struct cal_ctx *ctx)
 	return stopped;
 }
 
-static int
-cal_get_remote_frame_desc_entry(struct cal_ctx *ctx,
-				struct v4l2_mbus_frame_desc_entry *entry)
+int cal_ctx_prepare(struct cal_ctx *ctx)
 {
-	struct v4l2_mbus_frame_desc fd;
 	struct media_pad *phy_source_pad;
-	int ret;
 
 	phy_source_pad = media_pad_remote_pad_first(&ctx->pad);
 	if (!phy_source_pad)
 		return -ENODEV;
 
-	ret = v4l2_subdev_call(&ctx->phy->subdev, pad, get_frame_desc,
-			       phy_source_pad->index, &fd);
-	if (ret)
-		return ret;
+	struct v4l2_mbus_frame_desc *fd __free(v4l2_subdev_free_frame_desc) =
+		v4l2_subdev_get_frame_desc(&ctx->phy->subdev,
+					   phy_source_pad->index,
+					   V4L2_MBUS_FRAME_DESC_TYPE_CSI2);
+	if (IS_ERR(fd))
+		return PTR_ERR(fd);
 
-	if (fd.num_entries != 1)
+	if (fd->num_entries != 1)
 		return -EINVAL;
 
-	*entry = fd.entry[0];
+	ctx_dbg(2, ctx, "Framedesc: stream %u, len %u, vc %u, dt %#x\n",
+		fd->entry[0].stream, fd->entry[0].length,
+		fd->entry[0].bus.csi2.vc, fd->entry[0].bus.csi2.dt);
 
-	return 0;
-}
-
-int cal_ctx_prepare(struct cal_ctx *ctx)
-{
-	struct v4l2_mbus_frame_desc_entry entry;
-	int ret;
-
-	ret = cal_get_remote_frame_desc_entry(ctx, &entry);
-
-	if (ret == -ENOIOCTLCMD) {
-		ctx->vc = 0;
-		ctx->datatype = CAL_CSI2_CTX_DT_ANY;
-	} else if (!ret) {
-		ctx_dbg(2, ctx, "Framedesc: stream %u, len %u, vc %u, dt %#x\n",
-			entry.stream, entry.length, entry.bus.csi2.vc,
-			entry.bus.csi2.dt);
-
-		ctx->vc = entry.bus.csi2.vc;
-		ctx->datatype = entry.bus.csi2.dt;
-	} else {
-		return ret;
-	}
+	ctx->vc = fd->entry[0].bus.csi2.vc;
+	ctx->datatype = fd->entry[0].bus.csi2.dt;
 
 	ctx->use_pix_proc = ctx->vb_vidq.type == V4L2_BUF_TYPE_VIDEO_CAPTURE;
 
 	if (ctx->use_pix_proc) {
+		int ret;
+
 		ret = cal_reserve_pix_proc(ctx->cal);
 		if (ret < 0) {
 			ctx_err(ctx, "Failed to reserve pix proc: %d\n", ret);
-- 
2.47.3


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

* [PATCH v3 25/29] media: ipu6: Use v4l2_subdev_get_frame_desc()
  2026-08-24 12:14 [PATCH v3 00/29] Rework frame descriptors Sakari Ailus
                   ` (23 preceding siblings ...)
  2026-08-24 12:14 ` [PATCH v3 24/29] media: ti: cal: " Sakari Ailus
@ 2026-08-24 12:14 ` Sakari Ailus
  2026-08-24 21:26   ` Frank Li
  2026-08-24 12:14 ` [PATCH v3 26/29] staging: media: ipu7: " Sakari Ailus
                   ` (4 subsequent siblings)
  29 siblings, 1 reply; 67+ messages in thread
From: Sakari Ailus @ 2026-08-24 12:14 UTC (permalink / raw)
  To: linux-media
  Cc: laurent.pinchart, Dave Stevenson, Jacopo Mondi, Tomi Valkeinen,
	Jai Luthra, Mehdi Djait, Mattijs Korpershoek

Call v4l2_subdev_get_frame_desc() to obtain the frame descriptor. This is
preferred over calling the get_frame_desc() pad operation directly.

Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
---
 drivers/media/pci/intel/ipu6/ipu6-isys-csi2.c | 22 ++++++++-----------
 1 file changed, 9 insertions(+), 13 deletions(-)

diff --git a/drivers/media/pci/intel/ipu6/ipu6-isys-csi2.c b/drivers/media/pci/intel/ipu6/ipu6-isys-csi2.c
index 7e539a0c6c92..5317b01935a3 100644
--- a/drivers/media/pci/intel/ipu6/ipu6-isys-csi2.c
+++ b/drivers/media/pci/intel/ipu6/ipu6-isys-csi2.c
@@ -6,6 +6,7 @@
 #include <linux/atomic.h>
 #include <linux/bitfield.h>
 #include <linux/bits.h>
+#include <linux/cleanup.h>
 #include <linux/delay.h>
 #include <linux/device.h>
 #include <linux/err.h>
@@ -600,11 +601,9 @@ int ipu6_isys_csi2_get_remote_desc(u32 source_stream,
 {
 	struct v4l2_mbus_frame_desc_entry *desc_entry = NULL;
 	struct device *dev = &csi2->isys->adev->auxdev.dev;
-	struct v4l2_mbus_frame_desc desc;
 	struct v4l2_subdev *source;
 	struct media_pad *pad;
 	unsigned int i;
-	int ret;
 
 	source = media_entity_to_v4l2_subdev(source_entity);
 	if (!source)
@@ -614,18 +613,15 @@ int ipu6_isys_csi2_get_remote_desc(u32 source_stream,
 	if (!pad)
 		return -EPIPE;
 
-	ret = v4l2_subdev_call(source, pad, get_frame_desc, pad->index, &desc);
-	if (ret)
-		return ret;
-
-	if (desc.type != V4L2_MBUS_FRAME_DESC_TYPE_CSI2) {
-		dev_err(dev, "Unsupported frame descriptor type\n");
-		return -EINVAL;
-	}
+	struct v4l2_mbus_frame_desc *desc __free(v4l2_subdev_free_frame_desc) =
+		v4l2_subdev_get_frame_desc(source, pad->index,
+					   V4L2_MBUS_FRAME_DESC_TYPE_CSI2);
+	if (IS_ERR(desc))
+		return PTR_ERR(desc);
 
-	for (i = 0; i < desc.num_entries; i++) {
-		if (source_stream == desc.entry[i].stream) {
-			desc_entry = &desc.entry[i];
+	for (i = 0; i < desc->num_entries; i++) {
+		if (source_stream == desc->entry[i].stream) {
+			desc_entry = &desc->entry[i];
 			break;
 		}
 	}
-- 
2.47.3


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

* [PATCH v3 26/29] staging: media: ipu7: Use v4l2_subdev_get_frame_desc()
  2026-08-24 12:14 [PATCH v3 00/29] Rework frame descriptors Sakari Ailus
                   ` (24 preceding siblings ...)
  2026-08-24 12:14 ` [PATCH v3 25/29] media: ipu6: " Sakari Ailus
@ 2026-08-24 12:14 ` Sakari Ailus
  2026-08-24 21:27   ` Frank Li
  2026-08-24 12:14 ` [PATCH v3 27/29] media: cdns-csi2rc: " Sakari Ailus
                   ` (3 subsequent siblings)
  29 siblings, 1 reply; 67+ messages in thread
From: Sakari Ailus @ 2026-08-24 12:14 UTC (permalink / raw)
  To: linux-media
  Cc: laurent.pinchart, Dave Stevenson, Jacopo Mondi, Tomi Valkeinen,
	Jai Luthra, Mehdi Djait, Mattijs Korpershoek

Call v4l2_subdev_get_frame_desc() to obtain the frame descriptor. This is
preferred over calling the get_frame_desc() pad operation directly.

Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
---
 .../staging/media/ipu7/ipu7-isys-csi-phy.c    | 19 ++++++--------
 drivers/staging/media/ipu7/ipu7-isys-csi2.c   | 26 ++++++++-----------
 2 files changed, 19 insertions(+), 26 deletions(-)

diff --git a/drivers/staging/media/ipu7/ipu7-isys-csi-phy.c b/drivers/staging/media/ipu7/ipu7-isys-csi-phy.c
index 3f15af3b4c79..70f8a55e3bce 100644
--- a/drivers/staging/media/ipu7/ipu7-isys-csi-phy.c
+++ b/drivers/staging/media/ipu7/ipu7-isys-csi-phy.c
@@ -5,6 +5,7 @@
 
 #include <linux/bitmap.h>
 #include <linux/bug.h>
+#include <linux/cleanup.h>
 #include <linux/delay.h>
 #include <linux/device.h>
 #include <linux/iopoll.h>
@@ -300,7 +301,6 @@ static int ipu7_isys_csi_ctrl_dids_config(struct ipu7_isys_csi2 *csi2, u32 id)
 {
 	struct v4l2_mbus_frame_desc_entry *desc_entry = NULL;
 	struct device *dev = &csi2->isys->adev->auxdev.dev;
-	struct v4l2_mbus_frame_desc desc;
 	struct v4l2_subdev *ext_sd;
 	struct media_pad *pad;
 	unsigned int i;
@@ -318,17 +318,14 @@ static int ipu7_isys_csi_ctrl_dids_config(struct ipu7_isys_csi2 *csi2, u32 id)
 		 pad->entity->name))
 		return -ENODEV;
 
-	ret = v4l2_subdev_call(ext_sd, pad, get_frame_desc, pad->index, &desc);
-	if (ret)
-		return ret;
-
-	if (desc.type != V4L2_MBUS_FRAME_DESC_TYPE_CSI2) {
-		dev_warn(dev, "Unsupported frame descriptor type\n");
-		return -EINVAL;
-	}
+	struct v4l2_mbus_frame_desc *desc __free(v4l2_subdev_free_frame_desc) =
+		v4l2_subdev_get_frame_desc(ext_sd, pad->index,
+					   V4L2_MBUS_FRAME_DESC_TYPE_CSI2);
+	if (IS_ERR(desc))
+		return PTR_ERR(desc);
 
-	for (i = 0; i < desc.num_entries; i++) {
-		desc_entry = &desc.entry[i];
+	for (i = 0; i < desc->num_entries; i++) {
+		desc_entry = &desc->entry[i];
 		if (desc_entry->bus.csi2.vc < IPU7_NR_OF_CSI2_VC) {
 			ret = __dids_config(csi2, id, desc_entry->bus.csi2.vc,
 					    desc_entry->bus.csi2.dt);
diff --git a/drivers/staging/media/ipu7/ipu7-isys-csi2.c b/drivers/staging/media/ipu7/ipu7-isys-csi2.c
index f34eabfe8a98..08f4ca1e0289 100644
--- a/drivers/staging/media/ipu7/ipu7-isys-csi2.c
+++ b/drivers/staging/media/ipu7/ipu7-isys-csi2.c
@@ -6,6 +6,7 @@
 #include <linux/atomic.h>
 #include <linux/bits.h>
 #include <linux/bug.h>
+#include <linux/cleanup.h>
 #include <linux/delay.h>
 #include <linux/device.h>
 #include <linux/io.h>
@@ -491,11 +492,9 @@ int ipu7_isys_csi2_get_remote_desc(u32 source_stream,
 {
 	struct v4l2_mbus_frame_desc_entry *desc_entry = NULL;
 	struct device *dev = &csi2->isys->adev->auxdev.dev;
-	struct v4l2_mbus_frame_desc desc;
 	struct v4l2_subdev *source;
 	struct media_pad *pad;
 	unsigned int i;
-	int ret;
 
 	source = media_entity_to_v4l2_subdev(source_entity);
 	if (!source)
@@ -505,18 +504,15 @@ int ipu7_isys_csi2_get_remote_desc(u32 source_stream,
 	if (!pad)
 		return -EPIPE;
 
-	ret = v4l2_subdev_call(source, pad, get_frame_desc, pad->index, &desc);
-	if (ret)
-		return ret;
-
-	if (desc.type != V4L2_MBUS_FRAME_DESC_TYPE_CSI2) {
-		dev_err(dev, "Unsupported frame descriptor type\n");
-		return -EINVAL;
-	}
+	struct v4l2_mbus_frame_desc *desc __free(v4l2_subdev_free_frame_desc) =
+		v4l2_subdev_get_frame_desc(source, pad->index,
+					   V4L2_MBUS_FRAME_DESC_TYPE_CSI2);
+	if (IS_ERR(desc))
+		return PTR_ERR(desc);
 
-	for (i = 0; i < desc.num_entries; i++) {
-		if (source_stream == desc.entry[i].stream) {
-			desc_entry = &desc.entry[i];
+	for (i = 0; i < desc->num_entries; i++) {
+		if (source_stream == desc->entry[i].stream) {
+			desc_entry = &desc->entry[i];
 			break;
 		}
 	}
@@ -534,8 +530,8 @@ int ipu7_isys_csi2_get_remote_desc(u32 source_stream,
 
 	*entry = *desc_entry;
 
-	for (i = 0; i < desc.num_entries; i++) {
-		if (desc_entry->bus.csi2.vc == desc.entry[i].bus.csi2.vc)
+	for (i = 0; i < desc->num_entries; i++) {
+		if (desc_entry->bus.csi2.vc == desc->entry[i].bus.csi2.vc)
 			(*nr_queues)++;
 	}
 
-- 
2.47.3


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

* [PATCH v3 27/29] media: cdns-csi2rc: Use v4l2_subdev_get_frame_desc()
  2026-08-24 12:14 [PATCH v3 00/29] Rework frame descriptors Sakari Ailus
                   ` (25 preceding siblings ...)
  2026-08-24 12:14 ` [PATCH v3 26/29] staging: media: ipu7: " Sakari Ailus
@ 2026-08-24 12:14 ` Sakari Ailus
  2026-08-24 21:29   ` Frank Li
  2026-08-26  6:39   ` Jai Luthra
  2026-08-24 12:14 ` [PATCH v3 28/29] media: v4l2-subdev: Use v4l2_subdev_get_frame_desc() for passthrough Sakari Ailus
                   ` (2 subsequent siblings)
  29 siblings, 2 replies; 67+ messages in thread
From: Sakari Ailus @ 2026-08-24 12:14 UTC (permalink / raw)
  To: linux-media
  Cc: laurent.pinchart, Dave Stevenson, Jacopo Mondi, Tomi Valkeinen,
	Jai Luthra, Mehdi Djait, Mattijs Korpershoek

Call v4l2_subdev_get_frame_desc() to obtain the frame descriptor. This is
preferred over calling the get_frame_desc() pad operation directly.

Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
---
 drivers/media/platform/cadence/cdns-csi2rx.c | 24 ++++++++++----------
 1 file changed, 12 insertions(+), 12 deletions(-)

diff --git a/drivers/media/platform/cadence/cdns-csi2rx.c b/drivers/media/platform/cadence/cdns-csi2rx.c
index e31cdcd9ce8e..a1f4bf5fbc93 100644
--- a/drivers/media/platform/cadence/cdns-csi2rx.c
+++ b/drivers/media/platform/cadence/cdns-csi2rx.c
@@ -230,19 +230,20 @@ static const struct csi2rx_fmt *csi2rx_get_fmt_by_code(u32 code)
 	return NULL;
 }
 
-static int csi2rx_get_frame_desc_from_source(struct csi2rx_priv *csi2rx,
-					     struct v4l2_mbus_frame_desc *fd)
+static struct v4l2_mbus_frame_desc *
+csi2rx_get_frame_desc_from_source(struct csi2rx_priv *csi2rx)
 {
 	struct media_pad *remote_pad;
 
 	remote_pad = media_entity_remote_source_pad_unique(&csi2rx->subdev.entity);
 	if (IS_ERR(remote_pad)) {
 		dev_err(csi2rx->dev, "No remote pad found for sink\n");
-		return PTR_ERR(remote_pad);
+		return ERR_CAST(remote_pad);
 	}
 
-	return v4l2_subdev_call(csi2rx->source_subdev, pad, get_frame_desc,
-				remote_pad->index, fd);
+	return v4l2_subdev_get_frame_desc(csi2rx->source_subdev,
+					  remote_pad->index,
+					  V4L2_MBUS_FRAME_DESC_TYPE_CSI2);
 }
 
 static inline
@@ -459,13 +460,12 @@ static int csi2rx_log_status(struct v4l2_subdev *sd)
 static void csi2rx_update_vc_select(struct csi2rx_priv *csi2rx,
 				    struct v4l2_subdev_state *state)
 {
-	struct v4l2_mbus_frame_desc fd = {0};
 	struct v4l2_subdev_route *route;
 	unsigned int i;
-	int ret;
 
-	ret = csi2rx_get_frame_desc_from_source(csi2rx, &fd);
-	if (ret || fd.type != V4L2_MBUS_FRAME_DESC_TYPE_CSI2) {
+	struct v4l2_mbus_frame_desc __free(v4l2_subdev_free_frame_desc) *fd =
+		csi2rx_get_frame_desc_from_source(csi2rx);
+	if (IS_ERR(fd) || fd->type != V4L2_MBUS_FRAME_DESC_TYPE_CSI2) {
 		dev_dbg(csi2rx->dev,
 			"Failed to get source frame desc, allowing only VC=0\n");
 		for (i = 0; i < CSI2RX_STREAMS_MAX; i++)
@@ -479,12 +479,12 @@ static void csi2rx_update_vc_select(struct csi2rx_priv *csi2rx,
 	for_each_active_route(&state->routing, route) {
 		u32 cdns_stream = route->source_pad - CSI2RX_PAD_SOURCE_STREAM0;
 
-		for (i = 0; i < fd.num_entries; i++) {
-			if (fd.entry[i].stream != route->sink_stream)
+		for (i = 0; i < fd->num_entries; i++) {
+			if (fd->entry[i].stream != route->sink_stream)
 				continue;
 
 			csi2rx->vc_select[cdns_stream] |=
-				CSI2RX_STREAM_DATA_CFG_VC_SELECT(fd.entry[i].bus.csi2.vc);
+				CSI2RX_STREAM_DATA_CFG_VC_SELECT(fd->entry[i].bus.csi2.vc);
 		}
 	}
 }
-- 
2.47.3


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

* [PATCH v3 28/29] media: v4l2-subdev: Use v4l2_subdev_get_frame_desc() for passthrough
  2026-08-24 12:14 [PATCH v3 00/29] Rework frame descriptors Sakari Ailus
                   ` (26 preceding siblings ...)
  2026-08-24 12:14 ` [PATCH v3 27/29] media: cdns-csi2rc: " Sakari Ailus
@ 2026-08-24 12:14 ` Sakari Ailus
  2026-08-24 21:37   ` Frank Li
  2026-08-24 12:14 ` [PATCH v3 29/29] media: j721e-csi2rx: Use v4l2_subdev_get_frame_desc() Sakari Ailus
  2026-08-26  9:58 ` [PATCH v3 00/29] Rework frame descriptors Mattijs Korpershoek
  29 siblings, 1 reply; 67+ messages in thread
From: Sakari Ailus @ 2026-08-24 12:14 UTC (permalink / raw)
  To: linux-media
  Cc: laurent.pinchart, Dave Stevenson, Jacopo Mondi, Tomi Valkeinen,
	Jai Luthra, Mehdi Djait, Mattijs Korpershoek

Call v4l2_subdev_get_frame_desc() to obtain the frame descriptor in
__v4l2_subdev_get_frame_desc_passthrough(). This is preferred over calling
the get_frame_desc() pad operation directly.

Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
---
 drivers/media/v4l2-core/v4l2-subdev.c | 34 +++++++++++++--------------
 1 file changed, 17 insertions(+), 17 deletions(-)

diff --git a/drivers/media/v4l2-core/v4l2-subdev.c b/drivers/media/v4l2-core/v4l2-subdev.c
index 8c3c5b6e4ee8..2172bb8313ec 100644
--- a/drivers/media/v4l2-core/v4l2-subdev.c
+++ b/drivers/media/v4l2-core/v4l2-subdev.c
@@ -2558,6 +2558,7 @@ int __v4l2_subdev_get_frame_desc_passthrough(struct v4l2_subdev *sd,
 					     unsigned int pad,
 					     struct v4l2_mbus_frame_desc *fd)
 {
+	struct v4l2_mbus_frame_desc *source_fd = NULL;
 	struct media_pad *local_sink_pad;
 	struct v4l2_subdev_route *route;
 	struct device *dev = sd->dev;
@@ -2599,9 +2600,6 @@ int __v4l2_subdev_get_frame_desc_passthrough(struct v4l2_subdev *sd,
 
 	/* Iterate over sink pads */
 	media_entity_for_each_pad(&sd->entity, local_sink_pad) {
-		struct v4l2_mbus_frame_desc source_fd;
-		bool have_source_fd = false;
-
 		if (!(local_sink_pad->flags & MEDIA_PAD_FL_SINK))
 			continue;
 
@@ -2618,7 +2616,7 @@ int __v4l2_subdev_get_frame_desc_passthrough(struct v4l2_subdev *sd,
 			    route->sink_pad != local_sink_pad->index)
 				continue;
 
-			if (!have_source_fd) {
+			if (!source_fd) {
 				remote_source_pad = media_pad_remote_pad_unique(local_sink_pad);
 				if (IS_ERR(remote_source_pad)) {
 					dev_dbg(dev, "Failed to find remote pad for sink pad %u\n",
@@ -2633,33 +2631,31 @@ int __v4l2_subdev_get_frame_desc_passthrough(struct v4l2_subdev *sd,
 					goto err_free;
 				}
 
-				ret = v4l2_subdev_call(remote_sd, pad,
-						       get_frame_desc,
-						       remote_source_pad->index,
-						       &source_fd);
-				if (ret) {
+				source_fd = v4l2_subdev_get_frame_desc(remote_sd,
+								       remote_source_pad->index,
+								       fd->type);
+				if (IS_ERR(source_fd)) {
+					ret = PTR_ERR(source_fd);
 					dev_err(dev,
 						"Failed to get frame desc from remote subdev %s\n",
 						remote_sd->name);
 					goto err_free;
 				}
 
-				have_source_fd = true;
-
 				if (fd->num_entries == 0) {
-					fd->type = source_fd.type;
-				} else if (fd->type != source_fd.type) {
+					fd->type = source_fd->type;
+				} else if (fd->type != source_fd->type) {
 					dev_err(dev,
 						"Frame desc type mismatch: %u != %u\n",
-						fd->type, source_fd.type);
+						fd->type, source_fd->type);
 					ret = -EPIPE;
 					goto err_free;
 				}
 			}
 
-			for (unsigned int i = 0; i < source_fd.num_entries; i++) {
-				if (source_fd.entry[i].stream == route->sink_stream) {
-					source_entry = &source_fd.entry[i];
+			for (unsigned int i = 0; i < source_fd->num_entries; i++) {
+				if (source_fd->entry[i].stream == route->sink_stream) {
+					source_entry = &source_fd->entry[i];
 					break;
 				}
 			}
@@ -2684,11 +2680,15 @@ int __v4l2_subdev_get_frame_desc_passthrough(struct v4l2_subdev *sd,
 
 			fd->num_entries++;
 		}
+
+		v4l2_subdev_free_frame_desc(source_fd);
+		source_fd = NULL;
 	}
 
 	return 0;
 
 err_free:
+	v4l2_subdev_free_frame_desc(source_fd);
 	kfree(fd->entry);
 	fd->entry = fd->entry_mem;
 	fd->num_entries = 0;
-- 
2.47.3


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

* [PATCH v3 29/29] media: j721e-csi2rx: Use v4l2_subdev_get_frame_desc()
  2026-08-24 12:14 [PATCH v3 00/29] Rework frame descriptors Sakari Ailus
                   ` (27 preceding siblings ...)
  2026-08-24 12:14 ` [PATCH v3 28/29] media: v4l2-subdev: Use v4l2_subdev_get_frame_desc() for passthrough Sakari Ailus
@ 2026-08-24 12:14 ` Sakari Ailus
  2026-08-24 21:38   ` Frank Li
  2026-08-26  6:36   ` Jai Luthra
  2026-08-26  9:58 ` [PATCH v3 00/29] Rework frame descriptors Mattijs Korpershoek
  29 siblings, 2 replies; 67+ messages in thread
From: Sakari Ailus @ 2026-08-24 12:14 UTC (permalink / raw)
  To: linux-media
  Cc: laurent.pinchart, Dave Stevenson, Jacopo Mondi, Tomi Valkeinen,
	Jai Luthra, Mehdi Djait, Mattijs Korpershoek

Call v4l2_subdev_get_frame_desc() to obtain the frame descriptor. This is
preferred over calling the get_frame_desc() pad operation directly.

Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
---
 .../platform/ti/j721e-csi2rx/j721e-csi2rx.c   | 32 +++++++------------
 1 file changed, 12 insertions(+), 20 deletions(-)

diff --git a/drivers/media/platform/ti/j721e-csi2rx/j721e-csi2rx.c b/drivers/media/platform/ti/j721e-csi2rx/j721e-csi2rx.c
index 4769931b1930..9152f6ba6d7d 100644
--- a/drivers/media/platform/ti/j721e-csi2rx/j721e-csi2rx.c
+++ b/drivers/media/platform/ti/j721e-csi2rx/j721e-csi2rx.c
@@ -909,10 +909,7 @@ static int ti_csi2rx_get_vc_and_dt(struct ti_csi2rx_ctx *ctx)
 {
 	struct ti_csi2rx_dev *csi = ctx->csi;
 	struct ti_csi2rx_ctx *curr_ctx;
-	struct v4l2_mbus_frame_desc fd;
 	struct media_pad *source_pad;
-	const struct ti_csi2rx_fmt *fmt;
-	int ret;
 	unsigned int i, j;
 
 	/* Get the frame desc from source */
@@ -920,20 +917,15 @@ static int ti_csi2rx_get_vc_and_dt(struct ti_csi2rx_ctx *ctx)
 	if (IS_ERR(source_pad))
 		return PTR_ERR(source_pad);
 
-	ret = v4l2_subdev_call(csi->source, pad, get_frame_desc, source_pad->index, &fd);
-	if (ret) {
-		if (ret == -ENOIOCTLCMD) {
-			ctx->vc = 0;
-			fmt = find_format_by_fourcc(ctx->v_fmt.fmt.pix.pixelformat);
-			ctx->dt = fmt->csi_dt;
-		}
-		return ret;
-	}
-
-	if (fd.type != V4L2_MBUS_FRAME_DESC_TYPE_CSI2)
-		return -EINVAL;
+	struct v4l2_mbus_frame_desc *fd __free(v4l2_subdev_free_frame_desc) =
+		v4l2_subdev_get_frame_desc(csi->source, source_pad->index,
+					   V4L2_MBUS_FRAME_DESC_TYPE_CSI2);
+	if (IS_ERR(fd))
+		return PTR_ERR(fd);
 
 	for (i = 0; i < csi->num_ctx; i++) {
+		int ret;
+
 		curr_ctx = &csi->ctx[i];
 
 		/* Capture VC 0 by default */
@@ -943,15 +935,15 @@ static int ti_csi2rx_get_vc_and_dt(struct ti_csi2rx_ctx *ctx)
 		if (ret)
 			continue;
 
-		for (j = 0; j < fd.num_entries; j++) {
-			if (curr_ctx->stream == fd.entry[j].stream) {
-				curr_ctx->vc = fd.entry[j].bus.csi2.vc;
-				curr_ctx->dt = fd.entry[j].bus.csi2.dt;
+		for (j = 0; j < fd->num_entries; j++) {
+			if (curr_ctx->stream == fd->entry[j].stream) {
+				curr_ctx->vc = fd->entry[j].bus.csi2.vc;
+				curr_ctx->dt = fd->entry[j].bus.csi2.dt;
 				break;
 			}
 
 			/* Return error if no matching stream found */
-			if (j == fd.num_entries)
+			if (j == fd->num_entries)
 				return -EINVAL;
 		}
 	}
-- 
2.47.3


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

* Re: [PATCH v3 04/29] media: v4l2-subdev: Allow releasing frame descriptors on return
  2026-08-24 12:14 ` [PATCH v3 04/29] media: v4l2-subdev: Allow releasing frame descriptors on return Sakari Ailus
@ 2026-08-24 20:34   ` Frank Li
  0 siblings, 0 replies; 67+ messages in thread
From: Frank Li @ 2026-08-24 20:34 UTC (permalink / raw)
  To: Sakari Ailus
  Cc: linux-media, laurent.pinchart, Dave Stevenson, Jacopo Mondi,
	Tomi Valkeinen, Jai Luthra, Mehdi Djait, Mattijs Korpershoek

On Mon, Aug 24, 2026 at 03:14:26PM +0300, Sakari Ailus wrote:
> Use DEFINE_FREE() to allow using __free() to release frame descriptors
> using v4l2_subdev_free_frame_desc().
>
> Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
> ---

Reviewed-by: Frank Li <Frank.Li@nxp.com>

>  include/media/v4l2-subdev.h | 9 +++++++++
>  1 file changed, 9 insertions(+)
>
> diff --git a/include/media/v4l2-subdev.h b/include/media/v4l2-subdev.h
> index e7127953ac22..c10ca3f5d979 100644
> --- a/include/media/v4l2-subdev.h
> +++ b/include/media/v4l2-subdev.h
> @@ -1798,6 +1798,11 @@ int v4l2_subdev_get_frame_desc_passthrough(struct v4l2_subdev *sd,
>   * for each frame descriptor obtained by calling this function using
>   * v4l2_subdev_free_frame_desc().
>   *
> + * Use __free() to release the frame descriptor automatically::
> + *
> + *    struct v4l2_mbus_frame_desc *desc __free(v4l2_subdev_free_frame_desc) =
> + *            v4l2_subdev_get_frame_desc(sd, pad, desc);
> + *
>   * Return: The frame descriptor on success or a negative error code on failure.
>   */
>  struct v4l2_mbus_frame_desc *
> @@ -1812,6 +1817,10 @@ v4l2_subdev_get_frame_desc(struct v4l2_subdev *sd, unsigned int pad,
>   */
>  void v4l2_subdev_free_frame_desc(struct v4l2_mbus_frame_desc *desc);
>
> +DEFINE_FREE(v4l2_subdev_free_frame_desc, struct v4l2_mbus_frame_desc *, \
> +	    if (!IS_ERR_OR_NULL(_T))					\
> +		    v4l2_subdev_free_frame_desc(_T))
> +
>  #endif /* CONFIG_VIDEO_V4L2_SUBDEV_API */
>
>  #endif /* CONFIG_MEDIA_CONTROLLER */
> --
> 2.47.3
>

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

* Re: [PATCH v3 07/29] media: v4l2-subdev: Add frame descriptor passthrough for CSI-2 and DVP
  2026-08-24 12:14 ` [PATCH v3 07/29] media: v4l2-subdev: Add frame descriptor passthrough for CSI-2 and DVP Sakari Ailus
@ 2026-08-24 20:43   ` Frank Li
  0 siblings, 0 replies; 67+ messages in thread
From: Frank Li @ 2026-08-24 20:43 UTC (permalink / raw)
  To: Sakari Ailus
  Cc: linux-media, laurent.pinchart, Dave Stevenson, Jacopo Mondi,
	Tomi Valkeinen, Jai Luthra, Mehdi Djait, Mattijs Korpershoek

On Mon, Aug 24, 2026 at 03:14:29PM +0300, Sakari Ailus wrote:
> Add frame descriptor pass-through functions specific to MIPI CSI-2 and DVP
> (parallel) interfaces. The two new functions are needed in order to
> support frame descriptor-less sub-device drivers.
>
> Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
> ---

Reviewed-by: Frank Li <Frank.Li@nxp.com>

>  drivers/media/v4l2-core/v4l2-subdev.c | 20 +++++++++++
>  include/media/v4l2-subdev.h           | 49 +++++++++++++++++++++++++++
>  2 files changed, 69 insertions(+)
>
> diff --git a/drivers/media/v4l2-core/v4l2-subdev.c b/drivers/media/v4l2-core/v4l2-subdev.c
> index 071657459202..f5fa62038754 100644
> --- a/drivers/media/v4l2-core/v4l2-subdev.c
> +++ b/drivers/media/v4l2-core/v4l2-subdev.c
> @@ -2672,6 +2672,26 @@ int v4l2_subdev_get_frame_desc_passthrough(struct v4l2_subdev *sd,
>  }
>  EXPORT_SYMBOL_GPL(v4l2_subdev_get_frame_desc_passthrough);
>
> +int v4l2_subdev_get_frame_desc_passthrough_dvp(struct v4l2_subdev *sd,
> +					       unsigned int pad,
> +					       struct v4l2_mbus_frame_desc *fd)
> +{
> +	fd->type = V4L2_MBUS_FRAME_DESC_TYPE_PARALLEL;
> +
> +	return v4l2_subdev_get_frame_desc_passthrough(sd, pad, fd);
> +}
> +EXPORT_SYMBOL_GPL(v4l2_subdev_get_frame_desc_passthrough_dvp);
> +
> +int v4l2_subdev_get_frame_desc_passthrough_csi2(struct v4l2_subdev *sd,
> +						unsigned int pad,
> +						struct v4l2_mbus_frame_desc *fd)
> +{
> +	fd->type = V4L2_MBUS_FRAME_DESC_TYPE_CSI2;
> +
> +	return v4l2_subdev_get_frame_desc_passthrough(sd, pad, fd);
> +}
> +EXPORT_SYMBOL_GPL(v4l2_subdev_get_frame_desc_passthrough_csi2);
> +
>  struct v4l2_mbus_frame_desc *
>  v4l2_subdev_get_frame_desc(struct v4l2_subdev *sd, unsigned int pad,
>  			   enum v4l2_mbus_frame_desc_type type)
> diff --git a/include/media/v4l2-subdev.h b/include/media/v4l2-subdev.h
> index daebf8982c43..80ae7649f5c7 100644
> --- a/include/media/v4l2-subdev.h
> +++ b/include/media/v4l2-subdev.h
> @@ -1795,6 +1795,55 @@ int v4l2_subdev_get_frame_desc_passthrough(struct v4l2_subdev *sd,
>  					   unsigned int pad,
>  					   struct v4l2_mbus_frame_desc *fd);
>
> +/**
> + * v4l2_subdev_get_frame_desc_passthrough_dvp() - Helper to implement the subdev
> + *	get_frame_desc operation in simple passthrough cases for DVP
> + * @sd: The subdevice
> + * @pad: The source pad index
> + * @fd: The mbus frame desc
> + *
> + * This function locks the subdevice's active state, calls
> + * __v4l2_subdev_get_frame_desc_passthrough(), and unlocks the state.
> + *
> + * This function can be assigned directly as the .get_frame_desc callback in
> + * &v4l2_subdev_pad_ops for subdevices that pass streams through without
> + * modification. Drivers that need to perform additional work should use
> + * __v4l2_subdev_get_frame_desc_passthrough() in their custom
> + * .get_frame_desc implementation instead.
> + *
> + * This callback can be used for the DVP (Digital Video Port), also often called
> + * simply the "parallel interface".
> + *
> + * Return: 0 on success, or a negative error code otherwise.
> + */
> +int v4l2_subdev_get_frame_desc_passthrough_dvp(struct v4l2_subdev *sd,
> +					       unsigned int pad,
> +					       struct v4l2_mbus_frame_desc *fd);
> +
> +/**
> + * v4l2_subdev_get_frame_desc_passthrough_csi2() - Helper to implement the subdev
> + *	get_frame_desc operation in simple passthrough cases for MIPI CSI-2
> + * @sd: The subdevice
> + * @pad: The source pad index
> + * @fd: The mbus frame desc
> + *
> + * This function locks the subdevice's active state, calls
> + * __v4l2_subdev_get_frame_desc_passthrough(), and unlocks the state.
> + *
> + * This function can be assigned directly as the .get_frame_desc callback in
> + * &v4l2_subdev_pad_ops for subdevices that pass streams through without
> + * modification. Drivers that need to perform additional work should use
> + * __v4l2_subdev_get_frame_desc_passthrough() in their custom
> + * .get_frame_desc implementation instead.
> + *
> + * This callback can be used for the MIPI CSI-2 interface.
> + *
> + * Return: 0 on success, or a negative error code otherwise.
> + */
> +int v4l2_subdev_get_frame_desc_passthrough_csi2(struct v4l2_subdev *sd,
> +						unsigned int pad,
> +						struct v4l2_mbus_frame_desc *fd);
> +
>  /**
>   * v4l2_subdev_get_frame_desc() - Get a frame descriptor for a pad
>   * @sd: The sub-device
> --
> 2.47.3
>

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

* Re: [PATCH v3 08/29] media: ds90ub913: Use v4l2_subdev_get_frame_desc_passthrough_csi2()
  2026-08-24 12:14 ` [PATCH v3 08/29] media: ds90ub913: Use v4l2_subdev_get_frame_desc_passthrough_csi2() Sakari Ailus
@ 2026-08-24 20:44   ` Frank Li
  0 siblings, 0 replies; 67+ messages in thread
From: Frank Li @ 2026-08-24 20:44 UTC (permalink / raw)
  To: Sakari Ailus
  Cc: linux-media, laurent.pinchart, Dave Stevenson, Jacopo Mondi,
	Tomi Valkeinen, Jai Luthra, Mehdi Djait, Mattijs Korpershoek

On Mon, Aug 24, 2026 at 03:14:30PM +0300, Sakari Ailus wrote:
> Switch to v4l2_subdev_get_frame_desc_passthrough_csi2() in order to set
> the frame descriptor type in the get_frame_desc() callback.
>
> Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
> ---
Reviewed-by: Frank Li <Frank.Li@nxp.com>

>  drivers/media/i2c/ds90ub913.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/media/i2c/ds90ub913.c b/drivers/media/i2c/ds90ub913.c
> index 6abb5e324ae1..922865f03d37 100644
> --- a/drivers/media/i2c/ds90ub913.c
> +++ b/drivers/media/i2c/ds90ub913.c
> @@ -487,7 +487,7 @@ static const struct v4l2_subdev_pad_ops ub913_pad_ops = {
>  	.enable_streams = ub913_enable_streams,
>  	.disable_streams = ub913_disable_streams,
>  	.set_routing = ub913_set_routing,
> -	.get_frame_desc = v4l2_subdev_get_frame_desc_passthrough,
> +	.get_frame_desc = v4l2_subdev_get_frame_desc_passthrough_csi2,
>  	.get_fmt = v4l2_subdev_get_fmt,
>  	.set_fmt = ub913_set_fmt,
>  };
> --
> 2.47.3
>

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

* Re: [PATCH v3 09/29] media: ds90ub953: Use v4l2_subdev_get_frame_desc_passthrough_csi2()
  2026-08-24 12:14 ` [PATCH v3 09/29] media: ds90ub953: " Sakari Ailus
@ 2026-08-24 20:44   ` Frank Li
  0 siblings, 0 replies; 67+ messages in thread
From: Frank Li @ 2026-08-24 20:44 UTC (permalink / raw)
  To: Sakari Ailus
  Cc: linux-media, laurent.pinchart, Dave Stevenson, Jacopo Mondi,
	Tomi Valkeinen, Jai Luthra, Mehdi Djait, Mattijs Korpershoek

On Mon, Aug 24, 2026 at 03:14:31PM +0300, Sakari Ailus wrote:
> Switch to v4l2_subdev_get_frame_desc_passthrough_csi2() in order to set
> the frame descriptor type in the get_frame_desc() callback.
>
> Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
> ---
Reviewed-by: Frank Li <Frank.Li@nxp.com>

>  drivers/media/i2c/ds90ub953.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/media/i2c/ds90ub953.c b/drivers/media/i2c/ds90ub953.c
> index d4228e1134ff..1ed1ae90eaae 100644
> --- a/drivers/media/i2c/ds90ub953.c
> +++ b/drivers/media/i2c/ds90ub953.c
> @@ -635,7 +635,7 @@ static const struct v4l2_subdev_pad_ops ub953_pad_ops = {
>  	.enable_streams = ub953_enable_streams,
>  	.disable_streams = ub953_disable_streams,
>  	.set_routing = ub953_set_routing,
> -	.get_frame_desc = v4l2_subdev_get_frame_desc_passthrough,
> +	.get_frame_desc = v4l2_subdev_get_frame_desc_passthrough_csi2,
>  	.get_fmt = v4l2_subdev_get_fmt,
>  	.set_fmt = ub953_set_fmt,
>  };
> --
> 2.47.3
>

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

* Re: [PATCH v3 10/29] media: nxp: imx8-isi: Use v4l2_subdev_get_frame_desc_passthrough_csi2()
  2026-08-24 12:14 ` [PATCH v3 10/29] media: nxp: imx8-isi: " Sakari Ailus
@ 2026-08-24 20:44   ` Frank Li
  0 siblings, 0 replies; 67+ messages in thread
From: Frank Li @ 2026-08-24 20:44 UTC (permalink / raw)
  To: Sakari Ailus
  Cc: linux-media, laurent.pinchart, Dave Stevenson, Jacopo Mondi,
	Tomi Valkeinen, Jai Luthra, Mehdi Djait, Mattijs Korpershoek

On Mon, Aug 24, 2026 at 03:14:32PM +0300, Sakari Ailus wrote:
> Switch to v4l2_subdev_get_frame_desc_passthrough_csi2() in order to set
> the frame descriptor type in the get_frame_desc() callback.
>
> Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
> ---

Reviewed-by: Frank Li <Frank.Li@nxp.com>

>  drivers/media/platform/nxp/imx8-isi/imx8-isi-crossbar.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/media/platform/nxp/imx8-isi/imx8-isi-crossbar.c b/drivers/media/platform/nxp/imx8-isi/imx8-isi-crossbar.c
> index 7bb1335f2110..e6c38a769205 100644
> --- a/drivers/media/platform/nxp/imx8-isi/imx8-isi-crossbar.c
> +++ b/drivers/media/platform/nxp/imx8-isi/imx8-isi-crossbar.c
> @@ -462,7 +462,7 @@ static const struct v4l2_subdev_pad_ops mxc_isi_crossbar_subdev_pad_ops = {
>  	.enum_mbus_code = mxc_isi_crossbar_enum_mbus_code,
>  	.get_fmt = v4l2_subdev_get_fmt,
>  	.set_fmt = mxc_isi_crossbar_set_fmt,
> -	.get_frame_desc = v4l2_subdev_get_frame_desc_passthrough,
> +	.get_frame_desc = v4l2_subdev_get_frame_desc_passthrough_csi2,
>  	.set_routing = mxc_isi_crossbar_set_routing,
>  	.enable_streams = mxc_isi_crossbar_enable_streams,
>  	.disable_streams = mxc_isi_crossbar_disable_streams,
> --
> 2.47.3
>

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

* Re: [PATCH v3 11/29] media: rzg2l-cru: Use v4l2_subdev_get_frame_desc_passthrough_csi2()
  2026-08-24 12:14 ` [PATCH v3 11/29] media: rzg2l-cru: " Sakari Ailus
@ 2026-08-24 20:45   ` Frank Li
  0 siblings, 0 replies; 67+ messages in thread
From: Frank Li @ 2026-08-24 20:45 UTC (permalink / raw)
  To: Sakari Ailus
  Cc: linux-media, laurent.pinchart, Dave Stevenson, Jacopo Mondi,
	Tomi Valkeinen, Jai Luthra, Mehdi Djait, Mattijs Korpershoek

On Mon, Aug 24, 2026 at 03:14:33PM +0300, Sakari Ailus wrote:
> Switch to v4l2_subdev_get_frame_desc_passthrough_csi2() in order to set
> the frame descriptor type in the get_frame_desc() callback.
>
> Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
> ---

Reviewed-by: Frank Li <Frank.Li@nxp.com>

>  .../platform/renesas/rzg2l-cru/rzg2l-csi2.c   | 21 +------------------
>  1 file changed, 1 insertion(+), 20 deletions(-)
>
> diff --git a/drivers/media/platform/renesas/rzg2l-cru/rzg2l-csi2.c b/drivers/media/platform/renesas/rzg2l-cru/rzg2l-csi2.c
> index 6dc4b53607b4..472154c5ca9e 100644
> --- a/drivers/media/platform/renesas/rzg2l-cru/rzg2l-csi2.c
> +++ b/drivers/media/platform/renesas/rzg2l-cru/rzg2l-csi2.c
> @@ -722,25 +722,6 @@ static int rzg2l_csi2_enum_frame_size(struct v4l2_subdev *sd,
>  	return 0;
>  }
>
> -static int rzg2l_csi2_get_frame_desc(struct v4l2_subdev *sd, unsigned int pad,
> -				     struct v4l2_mbus_frame_desc *fd)
> -{
> -	struct rzg2l_csi2 *csi2 = sd_to_csi2(sd);
> -	struct media_pad *remote_pad;
> -
> -	if (!csi2->remote_source)
> -		return -ENODEV;
> -
> -	remote_pad = media_pad_remote_pad_unique(&csi2->pads[RZG2L_CSI2_SINK]);
> -	if (IS_ERR(remote_pad)) {
> -		dev_err(csi2->dev, "can't get source pad of %s (%pe)\n",
> -			csi2->remote_source->name, remote_pad);
> -		return PTR_ERR(remote_pad);
> -	}
> -	return v4l2_subdev_call(csi2->remote_source, pad, get_frame_desc,
> -				remote_pad->index, fd);
> -}
> -
>  static const struct v4l2_subdev_video_ops rzg2l_csi2_video_ops = {
>  	.s_stream = rzg2l_csi2_s_stream,
>  	.pre_streamon = rzg2l_csi2_pre_streamon,
> @@ -752,7 +733,7 @@ static const struct v4l2_subdev_pad_ops rzg2l_csi2_pad_ops = {
>  	.enum_frame_size = rzg2l_csi2_enum_frame_size,
>  	.set_fmt = rzg2l_csi2_set_format,
>  	.get_fmt = v4l2_subdev_get_fmt,
> -	.get_frame_desc = rzg2l_csi2_get_frame_desc,
> +	.get_frame_desc = v4l2_subdev_get_frame_desc_passthrough_csi2,
>  };
>
>  static const struct v4l2_subdev_ops rzg2l_csi2_subdev_ops = {
> --
> 2.47.3
>

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

* Re: [PATCH v3 12/29] media: dw-mipi-csi2rx: Use v4l2_subdev_get_frame_desc_passthrough_csi2()
  2026-08-24 12:14 ` [PATCH v3 12/29] media: dw-mipi-csi2rx: " Sakari Ailus
@ 2026-08-24 20:46   ` Frank Li
  0 siblings, 0 replies; 67+ messages in thread
From: Frank Li @ 2026-08-24 20:46 UTC (permalink / raw)
  To: Sakari Ailus
  Cc: linux-media, laurent.pinchart, Dave Stevenson, Jacopo Mondi,
	Tomi Valkeinen, Jai Luthra, Mehdi Djait, Mattijs Korpershoek

On Mon, Aug 24, 2026 at 03:14:34PM +0300, Sakari Ailus wrote:
> Switch to v4l2_subdev_get_frame_desc_passthrough_csi2() in order to set
> the frame descriptor type in the get_frame_desc() callback.
>
> Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
> ---

Reviewed-by: Frank Li <Frank.Li@nxp.com>

>  .../media/platform/synopsys/dw-mipi-csi2rx.c  | 22 +------------------
>  1 file changed, 1 insertion(+), 21 deletions(-)
>
> diff --git a/drivers/media/platform/synopsys/dw-mipi-csi2rx.c b/drivers/media/platform/synopsys/dw-mipi-csi2rx.c
> index 41e48365167e..9e3c97f9cad5 100644
> --- a/drivers/media/platform/synopsys/dw-mipi-csi2rx.c
> +++ b/drivers/media/platform/synopsys/dw-mipi-csi2rx.c
> @@ -630,31 +630,11 @@ static int dw_mipi_csi2rx_disable_streams(struct v4l2_subdev *sd,
>  	return ret;
>  }
>
> -static int
> -dw_mipi_csi2rx_get_frame_desc(struct v4l2_subdev *sd, unsigned int pad,
> -			      struct v4l2_mbus_frame_desc *fd)
> -{
> -	struct dw_mipi_csi2rx_device *csi2 = to_csi2(sd);
> -	struct v4l2_subdev *remote_sd;
> -	struct media_pad *remote_pad;
> -
> -	remote_pad = media_pad_remote_pad_unique(&csi2->pads[DW_MIPI_CSI2RX_PAD_SINK]);
> -	if (IS_ERR(remote_pad)) {
> -		dev_err(csi2->dev, "can't get remote source pad\n");
> -		return PTR_ERR(remote_pad);
> -	}
> -
> -	remote_sd = media_entity_to_v4l2_subdev(remote_pad->entity);
> -
> -	return v4l2_subdev_call(remote_sd, pad, get_frame_desc,
> -				remote_pad->index, fd);
> -}
> -
>  static const struct v4l2_subdev_pad_ops dw_mipi_csi2rx_pad_ops = {
>  	.enum_mbus_code = dw_mipi_csi2rx_enum_mbus_code,
>  	.get_fmt = v4l2_subdev_get_fmt,
>  	.set_fmt = dw_mipi_csi2rx_set_fmt,
> -	.get_frame_desc = dw_mipi_csi2rx_get_frame_desc,
> +	.get_frame_desc = v4l2_subdev_get_frame_desc_passthrough_csi2,
>  	.set_routing = dw_mipi_csi2rx_set_routing,
>  	.enable_streams = dw_mipi_csi2rx_enable_streams,
>  	.disable_streams = dw_mipi_csi2rx_disable_streams,
> --
> 2.47.3
>

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

* Re: [PATCH v3 13/29] media: cdn-csi2rc: media: Use v4l2_subdev_get_frame_desc_passthrough_csi2()
  2026-08-24 12:14 ` [PATCH v3 13/29] media: cdn-csi2rc: media: " Sakari Ailus
@ 2026-08-24 20:47   ` Frank Li
  2026-08-26  6:41   ` Jai Luthra
  1 sibling, 0 replies; 67+ messages in thread
From: Frank Li @ 2026-08-24 20:47 UTC (permalink / raw)
  To: Sakari Ailus
  Cc: linux-media, laurent.pinchart, Dave Stevenson, Jacopo Mondi,
	Tomi Valkeinen, Jai Luthra, Mehdi Djait, Mattijs Korpershoek

On Mon, Aug 24, 2026 at 03:14:35PM +0300, Sakari Ailus wrote:
> Switch to v4l2_subdev_get_frame_desc_passthrough_csi2() in order to allow
> compatibility with drivers that do not implement get_frame_desc() pad op.
>
> Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
> ---

Reviewed-by: Frank Li <Frank.Li@nxp.com>

>  drivers/media/platform/cadence/cdns-csi2rx.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/media/platform/cadence/cdns-csi2rx.c b/drivers/media/platform/cadence/cdns-csi2rx.c
> index 1ff2d8f78d5b..e31cdcd9ce8e 100644
> --- a/drivers/media/platform/cadence/cdns-csi2rx.c
> +++ b/drivers/media/platform/cadence/cdns-csi2rx.c
> @@ -722,7 +722,7 @@ static const struct v4l2_subdev_pad_ops csi2rx_pad_ops = {
>  	.enum_mbus_code		= csi2rx_enum_mbus_code,
>  	.get_fmt		= v4l2_subdev_get_fmt,
>  	.set_fmt		= csi2rx_set_fmt,
> -	.get_frame_desc		= v4l2_subdev_get_frame_desc_passthrough,
> +	.get_frame_desc		= v4l2_subdev_get_frame_desc_passthrough_csi2,
>  	.set_routing		= csi2rx_set_routing,
>  	.enable_streams		= csi2rx_enable_streams,
>  	.disable_streams	= csi2rx_disable_streams,
> --
> 2.47.3
>

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

* Re: [PATCH v3 14/29] media: v4l2-subdev: Make v4l2_subdev_get_frame_desc_passthrough() static
  2026-08-24 12:14 ` [PATCH v3 14/29] media: v4l2-subdev: Make v4l2_subdev_get_frame_desc_passthrough() static Sakari Ailus
@ 2026-08-24 20:48   ` Frank Li
  0 siblings, 0 replies; 67+ messages in thread
From: Frank Li @ 2026-08-24 20:48 UTC (permalink / raw)
  To: Sakari Ailus
  Cc: linux-media, laurent.pinchart, Dave Stevenson, Jacopo Mondi,
	Tomi Valkeinen, Jai Luthra, Mehdi Djait, Mattijs Korpershoek

On Mon, Aug 24, 2026 at 03:14:36PM +0300, Sakari Ailus wrote:
> No driver uses (nor should use) v4l2_subdev_get_frame_desc_passthrough()
> anymore, make it static.
>
> Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
> ---

Reviewed-by: Frank Li <Frank.Li@nxp.com>

>  drivers/media/v4l2-core/v4l2-subdev.c |  8 ++++----
>  include/media/v4l2-subdev.h           | 22 ----------------------
>  2 files changed, 4 insertions(+), 26 deletions(-)
>
> diff --git a/drivers/media/v4l2-core/v4l2-subdev.c b/drivers/media/v4l2-core/v4l2-subdev.c
> index f5fa62038754..c9f38b0313eb 100644
> --- a/drivers/media/v4l2-core/v4l2-subdev.c
> +++ b/drivers/media/v4l2-core/v4l2-subdev.c
> @@ -2655,9 +2655,10 @@ int __v4l2_subdev_get_frame_desc_passthrough(struct v4l2_subdev *sd,
>  }
>  EXPORT_SYMBOL_GPL(__v4l2_subdev_get_frame_desc_passthrough);
>
> -int v4l2_subdev_get_frame_desc_passthrough(struct v4l2_subdev *sd,
> -					   unsigned int pad,
> -					   struct v4l2_mbus_frame_desc *fd)
> +static int
> +v4l2_subdev_get_frame_desc_passthrough(struct v4l2_subdev *sd,
> +				       unsigned int pad,
> +				       struct v4l2_mbus_frame_desc *fd)
>  {
>  	struct v4l2_subdev_state *state;
>  	int ret;
> @@ -2670,7 +2671,6 @@ int v4l2_subdev_get_frame_desc_passthrough(struct v4l2_subdev *sd,
>
>  	return ret;
>  }
> -EXPORT_SYMBOL_GPL(v4l2_subdev_get_frame_desc_passthrough);
>
>  int v4l2_subdev_get_frame_desc_passthrough_dvp(struct v4l2_subdev *sd,
>  					       unsigned int pad,
> diff --git a/include/media/v4l2-subdev.h b/include/media/v4l2-subdev.h
> index 80ae7649f5c7..cfe285f44f57 100644
> --- a/include/media/v4l2-subdev.h
> +++ b/include/media/v4l2-subdev.h
> @@ -1773,28 +1773,6 @@ int __v4l2_subdev_get_frame_desc_passthrough(struct v4l2_subdev *sd,
>  					     unsigned int pad,
>  					     struct v4l2_mbus_frame_desc *fd);
>
> -/**
> - * v4l2_subdev_get_frame_desc_passthrough() - Helper to implement the subdev
> - *	get_frame_desc operation in simple passthrough cases
> - * @sd: The subdevice
> - * @pad: The source pad index
> - * @fd: The mbus frame desc
> - *
> - * This function locks the subdevice's active state, calls
> - * __v4l2_subdev_get_frame_desc_passthrough(), and unlocks the state.
> - *
> - * This function can be assigned directly as the .get_frame_desc callback in
> - * &v4l2_subdev_pad_ops for subdevices that pass streams through without
> - * modification. Drivers that need to perform additional work should use
> - * __v4l2_subdev_get_frame_desc_passthrough() in their custom
> - * .get_frame_desc implementation instead.
> - *
> - * Return: 0 on success, or a negative error code otherwise.
> - */
> -int v4l2_subdev_get_frame_desc_passthrough(struct v4l2_subdev *sd,
> -					   unsigned int pad,
> -					   struct v4l2_mbus_frame_desc *fd);
> -
>  /**
>   * v4l2_subdev_get_frame_desc_passthrough_dvp() - Helper to implement the subdev
>   *	get_frame_desc operation in simple passthrough cases for DVP
> --
> 2.47.3
>

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

* Re: [PATCH v3 15/29] media: v4l2-subdev: Return dynamically allocated pass-through routes
  2026-08-24 12:14 ` [PATCH v3 15/29] media: v4l2-subdev: Return dynamically allocated pass-through routes Sakari Ailus
@ 2026-08-24 21:00   ` Frank Li
  2026-08-25  7:36     ` Sakari Ailus
  0 siblings, 1 reply; 67+ messages in thread
From: Frank Li @ 2026-08-24 21:00 UTC (permalink / raw)
  To: Sakari Ailus
  Cc: linux-media, laurent.pinchart, Dave Stevenson, Jacopo Mondi,
	Tomi Valkeinen, Jai Luthra, Mehdi Djait, Mattijs Korpershoek

On Mon, Aug 24, 2026 at 03:14:37PM +0300, Sakari Ailus wrote:
> Count the number of pass-through routes, allocate memory and then return
> the full table to the caller.
>
> Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
> ---
>  drivers/media/v4l2-core/v4l2-subdev.c | 61 +++++++++++++++++++++++----
>  1 file changed, 52 insertions(+), 9 deletions(-)
>
> diff --git a/drivers/media/v4l2-core/v4l2-subdev.c b/drivers/media/v4l2-core/v4l2-subdev.c
> index c9f38b0313eb..d34704aad88e 100644
> --- a/drivers/media/v4l2-core/v4l2-subdev.c
> +++ b/drivers/media/v4l2-core/v4l2-subdev.c
> @@ -2561,13 +2561,42 @@ int __v4l2_subdev_get_frame_desc_passthrough(struct v4l2_subdev *sd,
>  	struct media_pad *local_sink_pad;
>  	struct v4l2_subdev_route *route;
>  	struct device *dev = sd->dev;
> -	int ret = 0;
> +	unsigned int num_entries = 0;
> +	int ret;
>
>  	lockdep_assert_held(state->lock);
>
>  	if (WARN_ON(!(sd->entity.pads[pad].flags & MEDIA_PAD_FL_SOURCE)))
>  		return -EINVAL;
>
> +	/* Count the number of entries first */
> +	media_entity_for_each_pad(&sd->entity, local_sink_pad) {
> +		if (!(local_sink_pad->flags & MEDIA_PAD_FL_SINK))
> +			continue;
> +
> +		for_each_active_route(&state->routing, route) {
> +			if (route->source_pad != pad ||
> +			    route->sink_pad != local_sink_pad->index)
> +				continue;
> +
> +			num_entries++;
> +
> +			if (num_entries > V4L2_FRAME_DESC_ENTRY_MAX)
> +				return -E2BIG;
> +		}
> +	}
> +
> +	if (num_entries > V4L2_FRAME_DESC_ENTRY_MAX)
> +		return -E2BIG;
> +
> +	if (num_entries > V4L2_FRAME_DESC_ENTRY_PREALLOC) {
> +		fd->entry = kzalloc_objs(*fd->entry, num_entries, GFP_KERNEL);

nit: Default should be GFP_KERNEL, needn't GFP_KERNEL when call kzalloc_objs()

Reviewed-by: Frank Li <Frank.Li@nxp.com>

> +		if (!fd->entry)
> +			return -ENOMEM;
> +
> +		fd->len_entries = num_entries;
> +	}
> +
>  	/* Iterate over sink pads */
>  	media_entity_for_each_pad(&sd->entity, local_sink_pad) {
>  		struct v4l2_mbus_frame_desc source_fd;
> @@ -2594,12 +2623,15 @@ int __v4l2_subdev_get_frame_desc_passthrough(struct v4l2_subdev *sd,
>  				if (IS_ERR(remote_source_pad)) {
>  					dev_dbg(dev, "Failed to find remote pad for sink pad %u\n",
>  						local_sink_pad->index);
> -					return PTR_ERR(remote_source_pad);
> +					ret = PTR_ERR(remote_source_pad);
> +					goto err_free;
>  				}
>
>  				remote_sd = media_entity_to_v4l2_subdev(remote_source_pad->entity);
> -				if (!remote_sd)
> -					return -EINVAL;
> +				if (!remote_sd) {
> +					ret = -EINVAL;
> +					goto err_free;
> +				}
>
>  				ret = v4l2_subdev_call(remote_sd, pad,
>  						       get_frame_desc,
> @@ -2609,7 +2641,7 @@ int __v4l2_subdev_get_frame_desc_passthrough(struct v4l2_subdev *sd,
>  					dev_err(dev,
>  						"Failed to get frame desc from remote subdev %s\n",
>  						remote_sd->name);
> -					return ret;
> +					goto err_free;
>  				}
>
>  				have_source_fd = true;
> @@ -2620,7 +2652,8 @@ int __v4l2_subdev_get_frame_desc_passthrough(struct v4l2_subdev *sd,
>  					dev_err(dev,
>  						"Frame desc type mismatch: %u != %u\n",
>  						fd->type, source_fd.type);
> -					return -EPIPE;
> +					ret = -EPIPE;
> +					goto err_free;
>  				}
>  			}
>
> @@ -2635,12 +2668,14 @@ int __v4l2_subdev_get_frame_desc_passthrough(struct v4l2_subdev *sd,
>  				dev_dbg(dev,
>  					"Failed to find stream %u from source frame desc\n",
>  					route->sink_stream);
> -				return -EPIPE;
> +				ret = -EPIPE;
> +				goto err_free;
>  			}
>
> -			if (fd->num_entries >= V4L2_FRAME_DESC_ENTRY_PREALLOC) {
> +			if (fd->num_entries >= fd->len_entries) {
>  				dev_dbg(dev, "Frame desc entry limit reached\n");
> -				return -E2BIG;
> +				ret = -E2BIG;
> +				goto err_free;
>  			}
>
>  			fd->entry[fd->num_entries] = *source_entry;
> @@ -2652,6 +2687,14 @@ int __v4l2_subdev_get_frame_desc_passthrough(struct v4l2_subdev *sd,
>  	}

Is it simpler if

	__free(kfree) *p = kzalloc_objs(*fd->entry, num_entries);

	fd->entry = no_free_ptr(p);
	fd->num_entries =
>
>  	return 0;
> +
> +err_free:
> +	kfree(fd->entry);
> +	fd->entry = fd->entry_mem;
> +	fd->num_entries = 0;
> +	fd->len_entries = V4L2_FRAME_DESC_ENTRY_PREALLOC;
> +
> +	return ret;
>  }
>  EXPORT_SYMBOL_GPL(__v4l2_subdev_get_frame_desc_passthrough);
>
> --
> 2.47.3
>

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

* Re: [PATCH v3 17/29] media: bcm2835-unicam: Use v4l2_subdev_get_frame_desc()
  2026-08-24 12:14 ` [PATCH v3 17/29] media: bcm2835-unicam: Use v4l2_subdev_get_frame_desc() Sakari Ailus
@ 2026-08-24 21:07   ` Frank Li
  2026-08-25  7:40     ` Sakari Ailus
  0 siblings, 1 reply; 67+ messages in thread
From: Frank Li @ 2026-08-24 21:07 UTC (permalink / raw)
  To: Sakari Ailus
  Cc: linux-media, laurent.pinchart, Dave Stevenson, Jacopo Mondi,
	Tomi Valkeinen, Jai Luthra, Mehdi Djait, Mattijs Korpershoek

On Mon, Aug 24, 2026 at 03:14:39PM +0300, Sakari Ailus wrote:
> Call v4l2_subdev_get_frame_desc() to obtain the frame descriptor. This is
> preferred over calling the get_frame_desc() pad operation directly.
>
> Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
> ---
>  .../media/platform/broadcom/bcm2835-unicam.c  | 22 +++++++++----------
>  1 file changed, 10 insertions(+), 12 deletions(-)
>
> diff --git a/drivers/media/platform/broadcom/bcm2835-unicam.c b/drivers/media/platform/broadcom/bcm2835-unicam.c
> index 14bb916dd7b1..2322d3df3915 100644
> --- a/drivers/media/platform/broadcom/bcm2835-unicam.c
> +++ b/drivers/media/platform/broadcom/bcm2835-unicam.c
> @@ -27,6 +27,7 @@
>   * output interface and V4L2 subdevice driver.
>   */
>
> +#include <linux/cleanup.h>
>  #include <linux/clk.h>
>  #include <linux/delay.h>
>  #include <linux/device.h>
> @@ -888,7 +889,6 @@ static int unicam_get_image_vc_dt(struct unicam_device *unicam,
>  				  struct v4l2_subdev_state *state,
>  				  u8 *vc, u8 *dt)
>  {
> -	struct v4l2_mbus_frame_desc fd;
>  	u32 stream;
>  	int ret;
>
> @@ -898,17 +898,15 @@ static int unicam_get_image_vc_dt(struct unicam_device *unicam,
>  	if (ret)
>  		return ret;
>
> -	ret = v4l2_subdev_call(unicam->sensor.subdev, pad, get_frame_desc,
> -			       unicam->sensor.pad->index, &fd);
> -	if (ret)
> -		return ret;
> -
> -	/* Only CSI-2 supports DTs. */
> -	if (fd.type != V4L2_MBUS_FRAME_DESC_TYPE_CSI2)
> -		return -EINVAL;
> +	struct v4l2_mbus_frame_desc *fd __free(v4l2_subdev_free_frame_desc) =
> +		v4l2_subdev_get_frame_desc(unicam->sensor.subdev,
> +					   unicam->sensor.pad->index,
> +					   V4L2_MBUS_FRAME_DESC_TYPE_CSI2);
> +	if (IS_ERR(fd))
> +		return PTR_ERR(fd);
>
> -	for (unsigned int i = 0; i < fd.num_entries; ++i) {
> -		const struct v4l2_mbus_frame_desc_entry *fde = &fd.entry[i];
> +	for (unsigned int i = 0; i < fd->num_entries; ++i) {
> +		const struct v4l2_mbus_frame_desc_entry *fde = &fd->entry[i];
>
>  		if (fde->stream == stream) {
>  			*vc = fde->bus.csi2.vc;
> @@ -927,7 +925,7 @@ static void unicam_start_rx(struct unicam_device *unicam,
>  	const struct unicam_format_info *fmtinfo;
>  	const struct v4l2_mbus_framefmt *fmt;
>  	unsigned int line_int_freq;
> -	u8 vc, dt;
> +	u8 vc = 0, dt = 0;

not sure why need here,

if unicam_get_image_vc_dt() return failure, vc will be set to 0
if unicam_get_image_vc_dt() return success, vc will be expected value.

Frank

>  	u32 val;
>  	int ret;
>
> --
> 2.47.3
>

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

* Re: [PATCH v3 18/29] media: bcm2835-unicam: Remove frame descriptor workaround
  2026-08-24 12:14 ` [PATCH v3 18/29] media: bcm2835-unicam: Remove frame descriptor workaround Sakari Ailus
@ 2026-08-24 21:10   ` Frank Li
  2026-08-26 12:09     ` Sakari Ailus
  0 siblings, 1 reply; 67+ messages in thread
From: Frank Li @ 2026-08-24 21:10 UTC (permalink / raw)
  To: Sakari Ailus
  Cc: linux-media, laurent.pinchart, Dave Stevenson, Jacopo Mondi,
	Tomi Valkeinen, Jai Luthra, Mehdi Djait, Mattijs Korpershoek

On Mon, Aug 24, 2026 at 03:14:40PM +0300, Sakari Ailus wrote:
> As the v4l2_subdev_get_frame_desc() either returns a frame descriptor or
> returns an error, remove the workaround for drivers that didn't implement
> the get_frame_desc() pad op. Also handle v4l2_subdev_get_frame_desc()
> errors.
>
> Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
> ---
>  .../media/platform/broadcom/bcm2835-unicam.c  | 26 +++++++++----------
>  1 file changed, 12 insertions(+), 14 deletions(-)
>
> diff --git a/drivers/media/platform/broadcom/bcm2835-unicam.c b/drivers/media/platform/broadcom/bcm2835-unicam.c
> index 2322d3df3915..ba613966c333 100644
> --- a/drivers/media/platform/broadcom/bcm2835-unicam.c
> +++ b/drivers/media/platform/broadcom/bcm2835-unicam.c
> @@ -918,8 +918,8 @@ static int unicam_get_image_vc_dt(struct unicam_device *unicam,
>  	return -EINVAL;
>  }
>
> -static void unicam_start_rx(struct unicam_device *unicam,
> -			    struct v4l2_subdev_state *state)
> +static int unicam_start_rx(struct unicam_device *unicam,
> +			   struct v4l2_subdev_state *state)
>  {
>  	struct unicam_node *node = &unicam->node[UNICAM_IMAGE_NODE];
>  	const struct unicam_format_info *fmtinfo;
> @@ -933,7 +933,11 @@ static void unicam_start_rx(struct unicam_device *unicam,
>  	fmtinfo = unicam_find_format_by_code(fmt->code,
>  					     UNICAM_SD_PAD_SOURCE_IMAGE);
>  	if (WARN_ON(!fmtinfo))
> -		return;
> +		return -EINVAL;
> +
> +	ret = unicam_get_image_vc_dt(unicam, state, &vc, &dt);
> +	if (ret)
> +		return ret;
>
>  	/*
>  	 * Enable lane clocks. The register is structured as follows:
> @@ -1090,16 +1094,6 @@ static void unicam_start_rx(struct unicam_device *unicam,
>  	unicam_wr_dma_addr(node, node->cur_frm);
>  	unicam_set_packing_config(unicam, fmtinfo);
>
> -	ret = unicam_get_image_vc_dt(unicam, state, &vc, &dt);
> -	if (ret) {
> -		/*
> -		 * If the source doesn't support frame descriptors, default to
> -		 * VC 0 and use the DT corresponding to the format.
> -		 */
> -		vc = 0;
> -		dt = fmtinfo->csi_dt;
> -	}
> -

look likes vc=0, dt=0 change in patch 17 should be in this patch?

Frank

>  	unicam_cfg_image_id(unicam, vc, dt);
>
>  	val = unicam_reg_read(unicam, UNICAM_MISC);
> @@ -1118,6 +1112,8 @@ static void unicam_start_rx(struct unicam_device *unicam,
>  	 * sync correctly to the FS from the source.
>  	 */
>  	unicam_reg_write_field(unicam, UNICAM_ICTL, 1, UNICAM_TFC);
> +
> +	return 0;
>  }
>
>  static void unicam_start_metadata(struct unicam_device *unicam)
> @@ -1427,7 +1423,9 @@ static int unicam_sd_enable_streams(struct v4l2_subdev *sd,
>  			unicam_start_metadata(unicam);
>
>  		unicam->frame_started = false;
> -		unicam_start_rx(unicam, state);
> +		ret = unicam_start_rx(unicam, state);
> +		if (ret)
> +			return ret;
>  	}
>
>  	ret = v4l2_subdev_routing_find_opposite_end(&state->routing, pad, 0,
> --
> 2.47.3
>

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

* Re: [PATCH v3 20/29] media: raspberrypi: cfe: Use v4l2_subdev_get_frame_desc()
  2026-08-24 12:14 ` [PATCH v3 20/29] media: raspberrypi: cfe: " Sakari Ailus
@ 2026-08-24 21:11   ` Frank Li
  0 siblings, 0 replies; 67+ messages in thread
From: Frank Li @ 2026-08-24 21:11 UTC (permalink / raw)
  To: Sakari Ailus
  Cc: linux-media, laurent.pinchart, Dave Stevenson, Jacopo Mondi,
	Tomi Valkeinen, Jai Luthra, Mehdi Djait, Mattijs Korpershoek

On Mon, Aug 24, 2026 at 03:14:42PM +0300, Sakari Ailus wrote:
> Call v4l2_subdev_get_frame_desc() to obtain the frame descriptor. This is
> preferred over calling the get_frame_desc() pad operation directly. Also
> remove the workaround for drivers not implementing the get_frame_desc()
> pad op.
>
> Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
> ---
Reviewed-by: Frank Li <Frank.Li@nxp.com>

>  .../media/platform/raspberrypi/rp1-cfe/cfe.c  | 51 ++++---------------
>  1 file changed, 11 insertions(+), 40 deletions(-)
>
> diff --git a/drivers/media/platform/raspberrypi/rp1-cfe/cfe.c b/drivers/media/platform/raspberrypi/rp1-cfe/cfe.c
> index 8375ed3e97b9..e99a77e0878e 100644
> --- a/drivers/media/platform/raspberrypi/rp1-cfe/cfe.c
> +++ b/drivers/media/platform/raspberrypi/rp1-cfe/cfe.c
> @@ -6,6 +6,7 @@
>   * Copyright (c) 2023-2024 Ideas on Board Oy
>   */
>
> +#include <linux/cleanup.h>
>  #include <linux/clk.h>
>  #include <linux/debugfs.h>
>  #include <linux/delay.h>
> @@ -778,32 +779,9 @@ static irqreturn_t cfe_isr(int irq, void *dev)
>   * Stream helpers
>   */
>
> -static int cfe_get_vc_dt_fallback(struct cfe_device *cfe, u8 *vc, u8 *dt)
> -{
> -	struct v4l2_subdev_state *state;
> -	struct v4l2_mbus_framefmt *fmt;
> -	const struct cfe_fmt *cfe_fmt;
> -
> -	state = v4l2_subdev_get_locked_active_state(&cfe->csi2.sd);
> -
> -	fmt = v4l2_subdev_state_get_format(state, CSI2_PAD_SINK, 0);
> -	if (!fmt)
> -		return -EINVAL;
> -
> -	cfe_fmt = find_format_by_code(fmt->code);
> -	if (!cfe_fmt)
> -		return -EINVAL;
> -
> -	*vc = 0;
> -	*dt = cfe_fmt->csi_dt;
> -
> -	return 0;
> -}
> -
>  static int cfe_get_vc_dt(struct cfe_device *cfe, unsigned int channel, u8 *vc,
>  			 u8 *dt)
>  {
> -	struct v4l2_mbus_frame_desc remote_desc;
>  	struct v4l2_subdev_state *state;
>  	u32 sink_stream;
>  	unsigned int i;
> @@ -816,34 +794,27 @@ static int cfe_get_vc_dt(struct cfe_device *cfe, unsigned int channel, u8 *vc,
>  	if (ret)
>  		return ret;
>
> -	ret = v4l2_subdev_call(cfe->source_sd, pad, get_frame_desc,
> -			       cfe->source_pad, &remote_desc);
> -	if (ret == -ENOIOCTLCMD) {
> -		cfe_dbg(cfe, "source does not support get_frame_desc, use fallback\n");
> -		return cfe_get_vc_dt_fallback(cfe, vc, dt);
> -	} else if (ret) {
> +	struct v4l2_mbus_frame_desc *fd __free(v4l2_subdev_free_frame_desc) =
> +		v4l2_subdev_get_frame_desc(cfe->source_sd, cfe->source_pad,
> +					   V4L2_MBUS_FRAME_DESC_TYPE_CSI2);
> +	if (IS_ERR(fd)) {
>  		cfe_err(cfe, "Failed to get frame descriptor\n");
> -		return ret;
> -	}
> -
> -	if (remote_desc.type != V4L2_MBUS_FRAME_DESC_TYPE_CSI2) {
> -		cfe_err(cfe, "Frame descriptor does not describe CSI-2 link");
> -		return -EINVAL;
> +		return PTR_ERR(fd);
>  	}
>
> -	for (i = 0; i < remote_desc.num_entries; i++) {
> -		if (remote_desc.entry[i].stream == sink_stream)
> +	for (i = 0; i < fd->num_entries; i++) {
> +		if (fd->entry[i].stream == sink_stream)
>  			break;
>  	}
>
> -	if (i == remote_desc.num_entries) {
> +	if (i == fd->num_entries) {
>  		cfe_err(cfe, "Stream %u not found in remote frame desc\n",
>  			sink_stream);
>  		return -EINVAL;
>  	}
>
> -	*vc = remote_desc.entry[i].bus.csi2.vc;
> -	*dt = remote_desc.entry[i].bus.csi2.dt;
> +	*vc = fd->entry[i].bus.csi2.vc;
> +	*dt = fd->entry[i].bus.csi2.dt;
>
>  	return 0;
>  }
> --
> 2.47.3
>

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

* Re: [PATCH v3 21/29] media: rzg2l-cru: Use v4l2_subdev_get_frame_desc()
  2026-08-24 12:14 ` [PATCH v3 21/29] media: rzg2l-cru: " Sakari Ailus
@ 2026-08-24 21:13   ` Frank Li
  0 siblings, 0 replies; 67+ messages in thread
From: Frank Li @ 2026-08-24 21:13 UTC (permalink / raw)
  To: Sakari Ailus
  Cc: linux-media, laurent.pinchart, Dave Stevenson, Jacopo Mondi,
	Tomi Valkeinen, Jai Luthra, Mehdi Djait, Mattijs Korpershoek

On Mon, Aug 24, 2026 at 03:14:43PM +0300, Sakari Ailus wrote:
> Call v4l2_subdev_get_frame_desc() to obtain the frame descriptor. This is
> preferred over calling the get_frame_desc() pad operation directly.
>
> Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
> ---

Reviewed-by: Frank Li <Frank.Li@nxp.com>

>  .../platform/renesas/rzg2l-cru/rzg2l-video.c  | 27 +++++--------------
>  1 file changed, 7 insertions(+), 20 deletions(-)
>
> diff --git a/drivers/media/platform/renesas/rzg2l-cru/rzg2l-video.c b/drivers/media/platform/renesas/rzg2l-cru/rzg2l-video.c
> index 91eda5034248..90c074527e01 100644
> --- a/drivers/media/platform/renesas/rzg2l-cru/rzg2l-video.c
> +++ b/drivers/media/platform/renesas/rzg2l-cru/rzg2l-video.c
> @@ -11,6 +11,7 @@
>   * Copyright (C) 2008 Magnus Damm
>   */
>
> +#include <linux/cleanup.h>
>  #include <linux/clk.h>
>  #include <linux/delay.h>
>  #include <linux/pm_runtime.h>
> @@ -438,31 +439,17 @@ void rzg2l_cru_stop_image_processing(struct rzg2l_cru_dev *cru)
>
>  static int rzg2l_cru_get_virtual_channel(struct rzg2l_cru_dev *cru)
>  {
> -	struct v4l2_mbus_frame_desc fd = { };
>  	struct media_pad *remote_pad;
> -	int ret;
>
>  	remote_pad = media_pad_remote_pad_unique(&cru->ip.pads[RZG2L_CRU_IP_SINK]);
> -	ret = v4l2_subdev_call(cru->ip.remote, pad, get_frame_desc, remote_pad->index, &fd);
> -	if (ret < 0 && ret != -ENOIOCTLCMD) {
> -		dev_err(cru->dev, "get_frame_desc failed on IP remote subdev\n");
> -		return ret;
> -	}
> -	/* If remote subdev does not implement .get_frame_desc default to VC0. */
> -	if (ret == -ENOIOCTLCMD)
> -		return 0;
>
> -	if (fd.type != V4L2_MBUS_FRAME_DESC_TYPE_CSI2) {
> -		dev_err(cru->dev, "get_frame_desc returned invalid bus type %d\n", fd.type);
> -		return -EINVAL;
> -	}
> -
> -	if (!fd.num_entries) {
> -		dev_err(cru->dev, "get_frame_desc returned zero entries\n");
> -		return -EINVAL;
> -	}
> +	struct v4l2_mbus_frame_desc *fd __free(v4l2_subdev_free_frame_desc) =
> +		v4l2_subdev_get_frame_desc(cru->ip.remote, remote_pad->index,
> +					   V4L2_MBUS_FRAME_DESC_TYPE_CSI2);
> +	if (IS_ERR(fd))
> +		return PTR_ERR(fd);
>
> -	return fd.entry[0].bus.csi2.vc;
> +	return fd->entry[0].bus.csi2.vc;
>  }
>
>  void rzg3e_cru_enable_interrupts(struct rzg2l_cru_dev *cru)
> --
> 2.47.3
>

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

* Re: [PATCH v3 22/29] media: rkisp1: Use v4l2_subdev_get_frame_desc()
  2026-08-24 12:14 ` [PATCH v3 22/29] media: rkisp1: " Sakari Ailus
@ 2026-08-24 21:13   ` Frank Li
  0 siblings, 0 replies; 67+ messages in thread
From: Frank Li @ 2026-08-24 21:13 UTC (permalink / raw)
  To: Sakari Ailus
  Cc: linux-media, laurent.pinchart, Dave Stevenson, Jacopo Mondi,
	Tomi Valkeinen, Jai Luthra, Mehdi Djait, Mattijs Korpershoek

On Mon, Aug 24, 2026 at 03:14:44PM +0300, Sakari Ailus wrote:
> Call v4l2_subdev_get_frame_desc() to obtain the frame descriptor. This is
> preferred over calling the get_frame_desc() pad operation directly.
>
> Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
> ---

Reviewed-by: Frank Li <Frank.Li@nxp.com>

>  .../platform/rockchip/rkisp1/rkisp1-isp.c     | 21 ++++++++++---------
>  1 file changed, 11 insertions(+), 10 deletions(-)
>
> diff --git a/drivers/media/platform/rockchip/rkisp1/rkisp1-isp.c b/drivers/media/platform/rockchip/rkisp1/rkisp1-isp.c
> index 2311672cedb1..eb8e881759f7 100644
> --- a/drivers/media/platform/rockchip/rkisp1/rkisp1-isp.c
> +++ b/drivers/media/platform/rockchip/rkisp1/rkisp1-isp.c
> @@ -8,6 +8,7 @@
>   * Copyright (C) 2017 Rockchip Electronics Co., Ltd.
>   */
>
> +#include <linux/cleanup.h>
>  #include <linux/iopoll.h>
>  #include <linux/pm_runtime.h>
>  #include <linux/regmap.h>
> @@ -87,11 +88,9 @@ static int rkisp1_gasket_enable(struct rkisp1_device *rkisp1,
>  				struct media_pad *source)
>  {
>  	struct v4l2_subdev *source_sd;
> -	struct v4l2_mbus_frame_desc fd;
>  	unsigned int dt;
>  	u32 mask;
>  	u32 val;
> -	int ret;
>
>  	/*
>  	 * Configure and enable the gasket with the CSI-2 data type. Set the
> @@ -101,22 +100,24 @@ static int rkisp1_gasket_enable(struct rkisp1_device *rkisp1,
>  	 */
>
>  	source_sd = media_entity_to_v4l2_subdev(source->entity);
> -	ret = v4l2_subdev_call(source_sd, pad, get_frame_desc,
> -			       source->index, &fd);
> -	if (ret) {
> +
> +	struct v4l2_mbus_frame_desc *fd __free(v4l2_subdev_free_frame_desc) =
> +		v4l2_subdev_get_frame_desc(source_sd, source->index,
> +					   V4L2_MBUS_FRAME_DESC_TYPE_CSI2);
> +	if (IS_ERR(fd)) {
>  		dev_err(rkisp1->dev,
> -			"failed to get frame descriptor from '%s':%u: %d\n",
> -			source_sd->name, 0, ret);
> -		return ret;
> +			"failed to get frame descriptor from '%s':%u: %pe\n",
> +			source_sd->name, 0, fd);
> +		return PTR_ERR(fd);
>  	}
>
> -	if (fd.num_entries != 1) {
> +	if (fd->num_entries != 1) {
>  		dev_err(rkisp1->dev, "invalid frame descriptor for '%s':%u\n",
>  			source_sd->name, 0);
>  		return -EINVAL;
>  	}
>
> -	dt = fd.entry[0].bus.csi2.dt;
> +	dt = fd->entry[0].bus.csi2.dt;
>
>  	if (rkisp1->gasket_id == 0) {
>  		mask = ISP_DEWARP_CONTROL_MIPI_CSI1_HS_POLARITY
> --
> 2.47.3
>

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

* Re: [PATCH v3 23/29] media: exynos4-is: Use v4l2_subdev_get_frame_desc()
  2026-08-24 12:14 ` [PATCH v3 23/29] media: exynos4-is: " Sakari Ailus
@ 2026-08-24 21:22   ` Frank Li
  0 siblings, 0 replies; 67+ messages in thread
From: Frank Li @ 2026-08-24 21:22 UTC (permalink / raw)
  To: Sakari Ailus
  Cc: linux-media, laurent.pinchart, Dave Stevenson, Jacopo Mondi,
	Tomi Valkeinen, Jai Luthra, Mehdi Djait, Mattijs Korpershoek

On Mon, Aug 24, 2026 at 03:14:45PM +0300, Sakari Ailus wrote:
> Call v4l2_subdev_get_frame_desc() to obtain the frame descriptor. This is
> preferred over calling the get_frame_desc() pad operation directly.
>
> Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
> ---

Reviewed-by: Frank Li <Frank.Li@nxp.com>

>  .../platform/samsung/exynos4-is/fimc-capture.c | 18 ++++++++++++++----
>  1 file changed, 14 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/media/platform/samsung/exynos4-is/fimc-capture.c b/drivers/media/platform/samsung/exynos4-is/fimc-capture.c
> index d85811f4b8c5..b5749f9cba39 100644
> --- a/drivers/media/platform/samsung/exynos4-is/fimc-capture.c
> +++ b/drivers/media/platform/samsung/exynos4-is/fimc-capture.c
> @@ -6,6 +6,7 @@
>   * Sylwester Nawrocki <s.nawrocki@samsung.com>
>   */
>
> +#include <linux/cleanup.h>
>  #include <linux/module.h>
>  #include <linux/kernel.h>
>  #include <linux/types.h>
> @@ -853,7 +854,8 @@ static int fimc_get_sensor_frame_desc(struct v4l2_subdev *sensor,
>  				      struct v4l2_plane_pix_format *plane_fmt,
>  				      unsigned int num_planes, bool try)
>  {
> -	struct v4l2_mbus_frame_desc fd = { };
> +	struct v4l2_mbus_frame_desc *alloc_fd
> +		__free(v4l2_subdev_free_frame_desc) = NULL, fd = { };
>  	int i, ret;
>  	int pad;
>
> @@ -861,10 +863,18 @@ static int fimc_get_sensor_frame_desc(struct v4l2_subdev *sensor,
>  		fd.entry[i].length = plane_fmt[i].sizeimage;
>
>  	pad = sensor->entity.num_pads - 1;
> -	if (try)
> +	if (try) {
>  		ret = v4l2_subdev_call(sensor, pad, set_frame_desc, pad, &fd);
> -	else
> -		ret = v4l2_subdev_call(sensor, pad, get_frame_desc, pad, &fd);
> +	} else {
> +		alloc_fd = v4l2_subdev_get_frame_desc(sensor, pad,
> +						      V4L2_MBUS_FRAME_DESC_TYPE_CSI2);
> +		if (IS_ERR(alloc_fd)) {
> +			ret = PTR_ERR(alloc_fd);
> +		} else {
> +			fd = *alloc_fd;
> +			ret = 0;
> +		}
> +	}
>
>  	if (ret < 0)
>  		return ret;
> --
> 2.47.3
>

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

* Re: [PATCH v3 24/29] media: ti: cal: Use v4l2_subdev_get_frame_desc()
  2026-08-24 12:14 ` [PATCH v3 24/29] media: ti: cal: " Sakari Ailus
@ 2026-08-24 21:26   ` Frank Li
  2026-08-25  8:05     ` Sakari Ailus
  0 siblings, 1 reply; 67+ messages in thread
From: Frank Li @ 2026-08-24 21:26 UTC (permalink / raw)
  To: Sakari Ailus
  Cc: linux-media, laurent.pinchart, Dave Stevenson, Jacopo Mondi,
	Tomi Valkeinen, Jai Luthra, Mehdi Djait, Mattijs Korpershoek

On Mon, Aug 24, 2026 at 03:14:46PM +0300, Sakari Ailus wrote:
> Call v4l2_subdev_get_frame_desc() to obtain the frame descriptor. This is
> preferred over calling the get_frame_desc() pad operation directly.
>
> Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
> ---
>  drivers/media/platform/ti/cal/cal-camerarx.c | 26 +++++------
>  drivers/media/platform/ti/cal/cal.c          | 49 ++++++--------------
>  2 files changed, 27 insertions(+), 48 deletions(-)
>
> diff --git a/drivers/media/platform/ti/cal/cal-camerarx.c b/drivers/media/platform/ti/cal/cal-camerarx.c
> index 00a71dac0ff4..9ea1f3551d22 100644
> --- a/drivers/media/platform/ti/cal/cal-camerarx.c
> +++ b/drivers/media/platform/ti/cal/cal-camerarx.c
> @@ -9,6 +9,7 @@
>   *	Laurent Pinchart <laurent.pinchart@ideasonboard.com>
>   */
>
> +#include <linux/cleanup.h>
>  #include <linux/clk.h>
>  #include <linux/delay.h>
>  #include <linux/mfd/syscon.h>
> @@ -872,7 +873,8 @@ static int cal_camerarx_get_frame_desc(struct v4l2_subdev *sd, unsigned int pad,
>  				       struct v4l2_mbus_frame_desc *fd)
>  {
>  	struct cal_camerarx *phy = to_cal_camerarx(sd);
> -	struct v4l2_mbus_frame_desc remote_desc;
> +	struct v4l2_mbus_frame_desc *remote_desc
> +		__free(v4l2_subdev_free_frame_desc) = NULL;
>  	const struct media_pad *remote_pad;
>  	struct v4l2_subdev_state *state;
>  	u32 sink_stream;
> @@ -893,24 +895,20 @@ static int cal_camerarx_get_frame_desc(struct v4l2_subdev *sd, unsigned int pad,
>  		goto out_unlock;
>  	}
>
> -	ret = v4l2_subdev_call(phy->source, pad, get_frame_desc,
> -			       remote_pad->index, &remote_desc);
> -	if (ret)
> -		goto out_unlock;
> -
> -	if (remote_desc.type != V4L2_MBUS_FRAME_DESC_TYPE_CSI2) {
> -		cal_err(phy->cal,
> -			"Frame descriptor does not describe CSI-2 link");
> -		ret = -EINVAL;
> +	remote_desc =

cleanup prefer declean variable here
	struct v4l2_mbus_frame_desc *remote_desc __free(v4l2_subdev_free_frame_desc)
		=

Frank
> +		v4l2_subdev_get_frame_desc(phy->source, remote_pad->index,
> +					   V4L2_MBUS_FRAME_DESC_TYPE_CSI2);
> +	if (IS_ERR(remote_desc)) {
> +		ret = PTR_ERR(remote_desc);
>  		goto out_unlock;
>  	}
>
> -	for (i = 0; i < remote_desc.num_entries; i++) {
> -		if (remote_desc.entry[i].stream == sink_stream)
> +	for (i = 0; i < remote_desc->num_entries; i++) {
> +		if (remote_desc->entry[i].stream == sink_stream)
>  			break;
>  	}
>
> -	if (i == remote_desc.num_entries) {
> +	if (i == remote_desc->num_entries) {
>  		cal_err(phy->cal, "Stream %u not found in remote frame desc\n",
>  			sink_stream);
>  		ret = -EINVAL;
> @@ -919,7 +917,7 @@ static int cal_camerarx_get_frame_desc(struct v4l2_subdev *sd, unsigned int pad,
>
>  	fd->type = V4L2_MBUS_FRAME_DESC_TYPE_CSI2;
>  	fd->num_entries = 1;
> -	fd->entry[0] = remote_desc.entry[i];
> +	fd->entry[0] = remote_desc->entry[i];
>
>  out_unlock:
>  	v4l2_subdev_unlock_state(state);
> diff --git a/drivers/media/platform/ti/cal/cal.c b/drivers/media/platform/ti/cal/cal.c
> index b7e77b6b8950..20192f90d5b3 100644
> --- a/drivers/media/platform/ti/cal/cal.c
> +++ b/drivers/media/platform/ti/cal/cal.c
> @@ -445,55 +445,36 @@ static bool cal_ctx_wr_dma_stopped(struct cal_ctx *ctx)
>  	return stopped;
>  }
>
> -static int
> -cal_get_remote_frame_desc_entry(struct cal_ctx *ctx,
> -				struct v4l2_mbus_frame_desc_entry *entry)
> +int cal_ctx_prepare(struct cal_ctx *ctx)
>  {
> -	struct v4l2_mbus_frame_desc fd;
>  	struct media_pad *phy_source_pad;
> -	int ret;
>
>  	phy_source_pad = media_pad_remote_pad_first(&ctx->pad);
>  	if (!phy_source_pad)
>  		return -ENODEV;
>
> -	ret = v4l2_subdev_call(&ctx->phy->subdev, pad, get_frame_desc,
> -			       phy_source_pad->index, &fd);
> -	if (ret)
> -		return ret;
> +	struct v4l2_mbus_frame_desc *fd __free(v4l2_subdev_free_frame_desc) =
> +		v4l2_subdev_get_frame_desc(&ctx->phy->subdev,
> +					   phy_source_pad->index,
> +					   V4L2_MBUS_FRAME_DESC_TYPE_CSI2);
> +	if (IS_ERR(fd))
> +		return PTR_ERR(fd);
>
> -	if (fd.num_entries != 1)
> +	if (fd->num_entries != 1)
>  		return -EINVAL;
>
> -	*entry = fd.entry[0];
> +	ctx_dbg(2, ctx, "Framedesc: stream %u, len %u, vc %u, dt %#x\n",
> +		fd->entry[0].stream, fd->entry[0].length,
> +		fd->entry[0].bus.csi2.vc, fd->entry[0].bus.csi2.dt);
>
> -	return 0;
> -}
> -
> -int cal_ctx_prepare(struct cal_ctx *ctx)
> -{
> -	struct v4l2_mbus_frame_desc_entry entry;
> -	int ret;
> -
> -	ret = cal_get_remote_frame_desc_entry(ctx, &entry);
> -
> -	if (ret == -ENOIOCTLCMD) {
> -		ctx->vc = 0;
> -		ctx->datatype = CAL_CSI2_CTX_DT_ANY;
> -	} else if (!ret) {
> -		ctx_dbg(2, ctx, "Framedesc: stream %u, len %u, vc %u, dt %#x\n",
> -			entry.stream, entry.length, entry.bus.csi2.vc,
> -			entry.bus.csi2.dt);
> -
> -		ctx->vc = entry.bus.csi2.vc;
> -		ctx->datatype = entry.bus.csi2.dt;
> -	} else {
> -		return ret;
> -	}
> +	ctx->vc = fd->entry[0].bus.csi2.vc;
> +	ctx->datatype = fd->entry[0].bus.csi2.dt;
>
>  	ctx->use_pix_proc = ctx->vb_vidq.type == V4L2_BUF_TYPE_VIDEO_CAPTURE;
>
>  	if (ctx->use_pix_proc) {
> +		int ret;
> +
>  		ret = cal_reserve_pix_proc(ctx->cal);
>  		if (ret < 0) {
>  			ctx_err(ctx, "Failed to reserve pix proc: %d\n", ret);
> --
> 2.47.3
>

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

* Re: [PATCH v3 25/29] media: ipu6: Use v4l2_subdev_get_frame_desc()
  2026-08-24 12:14 ` [PATCH v3 25/29] media: ipu6: " Sakari Ailus
@ 2026-08-24 21:26   ` Frank Li
  0 siblings, 0 replies; 67+ messages in thread
From: Frank Li @ 2026-08-24 21:26 UTC (permalink / raw)
  To: Sakari Ailus
  Cc: linux-media, laurent.pinchart, Dave Stevenson, Jacopo Mondi,
	Tomi Valkeinen, Jai Luthra, Mehdi Djait, Mattijs Korpershoek

On Mon, Aug 24, 2026 at 03:14:47PM +0300, Sakari Ailus wrote:
> Call v4l2_subdev_get_frame_desc() to obtain the frame descriptor. This is
> preferred over calling the get_frame_desc() pad operation directly.
>
> Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
> ---
Reviewed-by: Frank Li <Frank.Li@nxp.com>
>  drivers/media/pci/intel/ipu6/ipu6-isys-csi2.c | 22 ++++++++-----------
>  1 file changed, 9 insertions(+), 13 deletions(-)
>
> diff --git a/drivers/media/pci/intel/ipu6/ipu6-isys-csi2.c b/drivers/media/pci/intel/ipu6/ipu6-isys-csi2.c
> index 7e539a0c6c92..5317b01935a3 100644
> --- a/drivers/media/pci/intel/ipu6/ipu6-isys-csi2.c
> +++ b/drivers/media/pci/intel/ipu6/ipu6-isys-csi2.c
> @@ -6,6 +6,7 @@
>  #include <linux/atomic.h>
>  #include <linux/bitfield.h>
>  #include <linux/bits.h>
> +#include <linux/cleanup.h>
>  #include <linux/delay.h>
>  #include <linux/device.h>
>  #include <linux/err.h>
> @@ -600,11 +601,9 @@ int ipu6_isys_csi2_get_remote_desc(u32 source_stream,
>  {
>  	struct v4l2_mbus_frame_desc_entry *desc_entry = NULL;
>  	struct device *dev = &csi2->isys->adev->auxdev.dev;
> -	struct v4l2_mbus_frame_desc desc;
>  	struct v4l2_subdev *source;
>  	struct media_pad *pad;
>  	unsigned int i;
> -	int ret;
>
>  	source = media_entity_to_v4l2_subdev(source_entity);
>  	if (!source)
> @@ -614,18 +613,15 @@ int ipu6_isys_csi2_get_remote_desc(u32 source_stream,
>  	if (!pad)
>  		return -EPIPE;
>
> -	ret = v4l2_subdev_call(source, pad, get_frame_desc, pad->index, &desc);
> -	if (ret)
> -		return ret;
> -
> -	if (desc.type != V4L2_MBUS_FRAME_DESC_TYPE_CSI2) {
> -		dev_err(dev, "Unsupported frame descriptor type\n");
> -		return -EINVAL;
> -	}
> +	struct v4l2_mbus_frame_desc *desc __free(v4l2_subdev_free_frame_desc) =
> +		v4l2_subdev_get_frame_desc(source, pad->index,
> +					   V4L2_MBUS_FRAME_DESC_TYPE_CSI2);
> +	if (IS_ERR(desc))
> +		return PTR_ERR(desc);
>
> -	for (i = 0; i < desc.num_entries; i++) {
> -		if (source_stream == desc.entry[i].stream) {
> -			desc_entry = &desc.entry[i];
> +	for (i = 0; i < desc->num_entries; i++) {
> +		if (source_stream == desc->entry[i].stream) {
> +			desc_entry = &desc->entry[i];
>  			break;
>  		}
>  	}
> --
> 2.47.3
>

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

* Re: [PATCH v3 26/29] staging: media: ipu7: Use v4l2_subdev_get_frame_desc()
  2026-08-24 12:14 ` [PATCH v3 26/29] staging: media: ipu7: " Sakari Ailus
@ 2026-08-24 21:27   ` Frank Li
  0 siblings, 0 replies; 67+ messages in thread
From: Frank Li @ 2026-08-24 21:27 UTC (permalink / raw)
  To: Sakari Ailus
  Cc: linux-media, laurent.pinchart, Dave Stevenson, Jacopo Mondi,
	Tomi Valkeinen, Jai Luthra, Mehdi Djait, Mattijs Korpershoek

On Mon, Aug 24, 2026 at 03:14:48PM +0300, Sakari Ailus wrote:
> Call v4l2_subdev_get_frame_desc() to obtain the frame descriptor. This is
> preferred over calling the get_frame_desc() pad operation directly.
>
> Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
> ---

Reviewed-by: Frank Li <Frank.Li@nxp.com>

>  .../staging/media/ipu7/ipu7-isys-csi-phy.c    | 19 ++++++--------
>  drivers/staging/media/ipu7/ipu7-isys-csi2.c   | 26 ++++++++-----------
>  2 files changed, 19 insertions(+), 26 deletions(-)
>
> diff --git a/drivers/staging/media/ipu7/ipu7-isys-csi-phy.c b/drivers/staging/media/ipu7/ipu7-isys-csi-phy.c
> index 3f15af3b4c79..70f8a55e3bce 100644
> --- a/drivers/staging/media/ipu7/ipu7-isys-csi-phy.c
> +++ b/drivers/staging/media/ipu7/ipu7-isys-csi-phy.c
> @@ -5,6 +5,7 @@
>
>  #include <linux/bitmap.h>
>  #include <linux/bug.h>
> +#include <linux/cleanup.h>
>  #include <linux/delay.h>
>  #include <linux/device.h>
>  #include <linux/iopoll.h>
> @@ -300,7 +301,6 @@ static int ipu7_isys_csi_ctrl_dids_config(struct ipu7_isys_csi2 *csi2, u32 id)
>  {
>  	struct v4l2_mbus_frame_desc_entry *desc_entry = NULL;
>  	struct device *dev = &csi2->isys->adev->auxdev.dev;
> -	struct v4l2_mbus_frame_desc desc;
>  	struct v4l2_subdev *ext_sd;
>  	struct media_pad *pad;
>  	unsigned int i;
> @@ -318,17 +318,14 @@ static int ipu7_isys_csi_ctrl_dids_config(struct ipu7_isys_csi2 *csi2, u32 id)
>  		 pad->entity->name))
>  		return -ENODEV;
>
> -	ret = v4l2_subdev_call(ext_sd, pad, get_frame_desc, pad->index, &desc);
> -	if (ret)
> -		return ret;
> -
> -	if (desc.type != V4L2_MBUS_FRAME_DESC_TYPE_CSI2) {
> -		dev_warn(dev, "Unsupported frame descriptor type\n");
> -		return -EINVAL;
> -	}
> +	struct v4l2_mbus_frame_desc *desc __free(v4l2_subdev_free_frame_desc) =
> +		v4l2_subdev_get_frame_desc(ext_sd, pad->index,
> +					   V4L2_MBUS_FRAME_DESC_TYPE_CSI2);
> +	if (IS_ERR(desc))
> +		return PTR_ERR(desc);
>
> -	for (i = 0; i < desc.num_entries; i++) {
> -		desc_entry = &desc.entry[i];
> +	for (i = 0; i < desc->num_entries; i++) {
> +		desc_entry = &desc->entry[i];
>  		if (desc_entry->bus.csi2.vc < IPU7_NR_OF_CSI2_VC) {
>  			ret = __dids_config(csi2, id, desc_entry->bus.csi2.vc,
>  					    desc_entry->bus.csi2.dt);
> diff --git a/drivers/staging/media/ipu7/ipu7-isys-csi2.c b/drivers/staging/media/ipu7/ipu7-isys-csi2.c
> index f34eabfe8a98..08f4ca1e0289 100644
> --- a/drivers/staging/media/ipu7/ipu7-isys-csi2.c
> +++ b/drivers/staging/media/ipu7/ipu7-isys-csi2.c
> @@ -6,6 +6,7 @@
>  #include <linux/atomic.h>
>  #include <linux/bits.h>
>  #include <linux/bug.h>
> +#include <linux/cleanup.h>
>  #include <linux/delay.h>
>  #include <linux/device.h>
>  #include <linux/io.h>
> @@ -491,11 +492,9 @@ int ipu7_isys_csi2_get_remote_desc(u32 source_stream,
>  {
>  	struct v4l2_mbus_frame_desc_entry *desc_entry = NULL;
>  	struct device *dev = &csi2->isys->adev->auxdev.dev;
> -	struct v4l2_mbus_frame_desc desc;
>  	struct v4l2_subdev *source;
>  	struct media_pad *pad;
>  	unsigned int i;
> -	int ret;
>
>  	source = media_entity_to_v4l2_subdev(source_entity);
>  	if (!source)
> @@ -505,18 +504,15 @@ int ipu7_isys_csi2_get_remote_desc(u32 source_stream,
>  	if (!pad)
>  		return -EPIPE;
>
> -	ret = v4l2_subdev_call(source, pad, get_frame_desc, pad->index, &desc);
> -	if (ret)
> -		return ret;
> -
> -	if (desc.type != V4L2_MBUS_FRAME_DESC_TYPE_CSI2) {
> -		dev_err(dev, "Unsupported frame descriptor type\n");
> -		return -EINVAL;
> -	}
> +	struct v4l2_mbus_frame_desc *desc __free(v4l2_subdev_free_frame_desc) =
> +		v4l2_subdev_get_frame_desc(source, pad->index,
> +					   V4L2_MBUS_FRAME_DESC_TYPE_CSI2);
> +	if (IS_ERR(desc))
> +		return PTR_ERR(desc);
>
> -	for (i = 0; i < desc.num_entries; i++) {
> -		if (source_stream == desc.entry[i].stream) {
> -			desc_entry = &desc.entry[i];
> +	for (i = 0; i < desc->num_entries; i++) {
> +		if (source_stream == desc->entry[i].stream) {
> +			desc_entry = &desc->entry[i];
>  			break;
>  		}
>  	}
> @@ -534,8 +530,8 @@ int ipu7_isys_csi2_get_remote_desc(u32 source_stream,
>
>  	*entry = *desc_entry;
>
> -	for (i = 0; i < desc.num_entries; i++) {
> -		if (desc_entry->bus.csi2.vc == desc.entry[i].bus.csi2.vc)
> +	for (i = 0; i < desc->num_entries; i++) {
> +		if (desc_entry->bus.csi2.vc == desc->entry[i].bus.csi2.vc)
>  			(*nr_queues)++;
>  	}
>
> --
> 2.47.3
>

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

* Re: [PATCH v3 27/29] media: cdns-csi2rc: Use v4l2_subdev_get_frame_desc()
  2026-08-24 12:14 ` [PATCH v3 27/29] media: cdns-csi2rc: " Sakari Ailus
@ 2026-08-24 21:29   ` Frank Li
  2026-08-26  6:39   ` Jai Luthra
  1 sibling, 0 replies; 67+ messages in thread
From: Frank Li @ 2026-08-24 21:29 UTC (permalink / raw)
  To: Sakari Ailus
  Cc: linux-media, laurent.pinchart, Dave Stevenson, Jacopo Mondi,
	Tomi Valkeinen, Jai Luthra, Mehdi Djait, Mattijs Korpershoek

On Mon, Aug 24, 2026 at 03:14:49PM +0300, Sakari Ailus wrote:
> Call v4l2_subdev_get_frame_desc() to obtain the frame descriptor. This is
> preferred over calling the get_frame_desc() pad operation directly.
>
> Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
> ---

Reviewed-by: Frank Li <Frank.Li@nxp.com>

>  drivers/media/platform/cadence/cdns-csi2rx.c | 24 ++++++++++----------
>  1 file changed, 12 insertions(+), 12 deletions(-)
>
> diff --git a/drivers/media/platform/cadence/cdns-csi2rx.c b/drivers/media/platform/cadence/cdns-csi2rx.c
> index e31cdcd9ce8e..a1f4bf5fbc93 100644
> --- a/drivers/media/platform/cadence/cdns-csi2rx.c
> +++ b/drivers/media/platform/cadence/cdns-csi2rx.c
> @@ -230,19 +230,20 @@ static const struct csi2rx_fmt *csi2rx_get_fmt_by_code(u32 code)
>  	return NULL;
>  }
>
> -static int csi2rx_get_frame_desc_from_source(struct csi2rx_priv *csi2rx,
> -					     struct v4l2_mbus_frame_desc *fd)
> +static struct v4l2_mbus_frame_desc *
> +csi2rx_get_frame_desc_from_source(struct csi2rx_priv *csi2rx)
>  {
>  	struct media_pad *remote_pad;
>
>  	remote_pad = media_entity_remote_source_pad_unique(&csi2rx->subdev.entity);
>  	if (IS_ERR(remote_pad)) {
>  		dev_err(csi2rx->dev, "No remote pad found for sink\n");
> -		return PTR_ERR(remote_pad);
> +		return ERR_CAST(remote_pad);
>  	}
>
> -	return v4l2_subdev_call(csi2rx->source_subdev, pad, get_frame_desc,
> -				remote_pad->index, fd);
> +	return v4l2_subdev_get_frame_desc(csi2rx->source_subdev,
> +					  remote_pad->index,
> +					  V4L2_MBUS_FRAME_DESC_TYPE_CSI2);
>  }
>
>  static inline
> @@ -459,13 +460,12 @@ static int csi2rx_log_status(struct v4l2_subdev *sd)
>  static void csi2rx_update_vc_select(struct csi2rx_priv *csi2rx,
>  				    struct v4l2_subdev_state *state)
>  {
> -	struct v4l2_mbus_frame_desc fd = {0};
>  	struct v4l2_subdev_route *route;
>  	unsigned int i;
> -	int ret;
>
> -	ret = csi2rx_get_frame_desc_from_source(csi2rx, &fd);
> -	if (ret || fd.type != V4L2_MBUS_FRAME_DESC_TYPE_CSI2) {
> +	struct v4l2_mbus_frame_desc __free(v4l2_subdev_free_frame_desc) *fd =
> +		csi2rx_get_frame_desc_from_source(csi2rx);
> +	if (IS_ERR(fd) || fd->type != V4L2_MBUS_FRAME_DESC_TYPE_CSI2) {
>  		dev_dbg(csi2rx->dev,
>  			"Failed to get source frame desc, allowing only VC=0\n");
>  		for (i = 0; i < CSI2RX_STREAMS_MAX; i++)
> @@ -479,12 +479,12 @@ static void csi2rx_update_vc_select(struct csi2rx_priv *csi2rx,
>  	for_each_active_route(&state->routing, route) {
>  		u32 cdns_stream = route->source_pad - CSI2RX_PAD_SOURCE_STREAM0;
>
> -		for (i = 0; i < fd.num_entries; i++) {
> -			if (fd.entry[i].stream != route->sink_stream)
> +		for (i = 0; i < fd->num_entries; i++) {
> +			if (fd->entry[i].stream != route->sink_stream)
>  				continue;
>
>  			csi2rx->vc_select[cdns_stream] |=
> -				CSI2RX_STREAM_DATA_CFG_VC_SELECT(fd.entry[i].bus.csi2.vc);
> +				CSI2RX_STREAM_DATA_CFG_VC_SELECT(fd->entry[i].bus.csi2.vc);
>  		}
>  	}
>  }
> --
> 2.47.3
>

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

* Re: [PATCH v3 28/29] media: v4l2-subdev: Use v4l2_subdev_get_frame_desc() for passthrough
  2026-08-24 12:14 ` [PATCH v3 28/29] media: v4l2-subdev: Use v4l2_subdev_get_frame_desc() for passthrough Sakari Ailus
@ 2026-08-24 21:37   ` Frank Li
  2026-08-25  7:34     ` Sakari Ailus
  0 siblings, 1 reply; 67+ messages in thread
From: Frank Li @ 2026-08-24 21:37 UTC (permalink / raw)
  To: Sakari Ailus
  Cc: linux-media, laurent.pinchart, Dave Stevenson, Jacopo Mondi,
	Tomi Valkeinen, Jai Luthra, Mehdi Djait, Mattijs Korpershoek

On Mon, Aug 24, 2026 at 03:14:50PM +0300, Sakari Ailus wrote:
> Call v4l2_subdev_get_frame_desc() to obtain the frame descriptor in
> __v4l2_subdev_get_frame_desc_passthrough(). This is preferred over calling
> the get_frame_desc() pad operation directly.
>
> Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
> ---
>  drivers/media/v4l2-core/v4l2-subdev.c | 34 +++++++++++++--------------
>  1 file changed, 17 insertions(+), 17 deletions(-)
>
> diff --git a/drivers/media/v4l2-core/v4l2-subdev.c b/drivers/media/v4l2-core/v4l2-subdev.c
> index 8c3c5b6e4ee8..2172bb8313ec 100644
> --- a/drivers/media/v4l2-core/v4l2-subdev.c
> +++ b/drivers/media/v4l2-core/v4l2-subdev.c
> @@ -2558,6 +2558,7 @@ int __v4l2_subdev_get_frame_desc_passthrough(struct v4l2_subdev *sd,
>  					     unsigned int pad,
>  					     struct v4l2_mbus_frame_desc *fd)
>  {
> +	struct v4l2_mbus_frame_desc *source_fd = NULL;

why not use auto cleanup like other patches? look like only use in loop
media_entity_for_each_pad()

Frank
>  	struct media_pad *local_sink_pad;
>  	struct v4l2_subdev_route *route;
>  	struct device *dev = sd->dev;
> @@ -2599,9 +2600,6 @@ int __v4l2_subdev_get_frame_desc_passthrough(struct v4l2_subdev *sd,
>
>  	/* Iterate over sink pads */
>  	media_entity_for_each_pad(&sd->entity, local_sink_pad) {
> -		struct v4l2_mbus_frame_desc source_fd;
> -		bool have_source_fd = false;
> -
>  		if (!(local_sink_pad->flags & MEDIA_PAD_FL_SINK))
>  			continue;
>
> @@ -2618,7 +2616,7 @@ int __v4l2_subdev_get_frame_desc_passthrough(struct v4l2_subdev *sd,
>  			    route->sink_pad != local_sink_pad->index)
>  				continue;
>
> -			if (!have_source_fd) {
> +			if (!source_fd) {
>  				remote_source_pad = media_pad_remote_pad_unique(local_sink_pad);
>  				if (IS_ERR(remote_source_pad)) {
>  					dev_dbg(dev, "Failed to find remote pad for sink pad %u\n",
> @@ -2633,33 +2631,31 @@ int __v4l2_subdev_get_frame_desc_passthrough(struct v4l2_subdev *sd,
>  					goto err_free;
>  				}
>
> -				ret = v4l2_subdev_call(remote_sd, pad,
> -						       get_frame_desc,
> -						       remote_source_pad->index,
> -						       &source_fd);
> -				if (ret) {
> +				source_fd = v4l2_subdev_get_frame_desc(remote_sd,
> +								       remote_source_pad->index,
> +								       fd->type);
> +				if (IS_ERR(source_fd)) {
> +					ret = PTR_ERR(source_fd);
>  					dev_err(dev,
>  						"Failed to get frame desc from remote subdev %s\n",
>  						remote_sd->name);
>  					goto err_free;
>  				}
>
> -				have_source_fd = true;
> -
>  				if (fd->num_entries == 0) {
> -					fd->type = source_fd.type;
> -				} else if (fd->type != source_fd.type) {
> +					fd->type = source_fd->type;
> +				} else if (fd->type != source_fd->type) {
>  					dev_err(dev,
>  						"Frame desc type mismatch: %u != %u\n",
> -						fd->type, source_fd.type);
> +						fd->type, source_fd->type);
>  					ret = -EPIPE;
>  					goto err_free;
>  				}
>  			}
>
> -			for (unsigned int i = 0; i < source_fd.num_entries; i++) {
> -				if (source_fd.entry[i].stream == route->sink_stream) {
> -					source_entry = &source_fd.entry[i];
> +			for (unsigned int i = 0; i < source_fd->num_entries; i++) {
> +				if (source_fd->entry[i].stream == route->sink_stream) {
> +					source_entry = &source_fd->entry[i];
>  					break;
>  				}
>  			}
> @@ -2684,11 +2680,15 @@ int __v4l2_subdev_get_frame_desc_passthrough(struct v4l2_subdev *sd,
>
>  			fd->num_entries++;
>  		}
> +
> +		v4l2_subdev_free_frame_desc(source_fd);
> +		source_fd = NULL;
>  	}
>
>  	return 0;
>
>  err_free:
> +	v4l2_subdev_free_frame_desc(source_fd);
>  	kfree(fd->entry);
>  	fd->entry = fd->entry_mem;
>  	fd->num_entries = 0;
> --
> 2.47.3
>

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

* Re: [PATCH v3 29/29] media: j721e-csi2rx: Use v4l2_subdev_get_frame_desc()
  2026-08-24 12:14 ` [PATCH v3 29/29] media: j721e-csi2rx: Use v4l2_subdev_get_frame_desc() Sakari Ailus
@ 2026-08-24 21:38   ` Frank Li
  2026-08-26  6:36   ` Jai Luthra
  1 sibling, 0 replies; 67+ messages in thread
From: Frank Li @ 2026-08-24 21:38 UTC (permalink / raw)
  To: Sakari Ailus
  Cc: linux-media, laurent.pinchart, Dave Stevenson, Jacopo Mondi,
	Tomi Valkeinen, Jai Luthra, Mehdi Djait, Mattijs Korpershoek

On Mon, Aug 24, 2026 at 03:14:51PM +0300, Sakari Ailus wrote:
> Call v4l2_subdev_get_frame_desc() to obtain the frame descriptor. This is
> preferred over calling the get_frame_desc() pad operation directly.
>
> Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
> ---

Reviewed-by: Frank Li <Frank.Li@nxp.com>

>  .../platform/ti/j721e-csi2rx/j721e-csi2rx.c   | 32 +++++++------------
>  1 file changed, 12 insertions(+), 20 deletions(-)
>
> diff --git a/drivers/media/platform/ti/j721e-csi2rx/j721e-csi2rx.c b/drivers/media/platform/ti/j721e-csi2rx/j721e-csi2rx.c
> index 4769931b1930..9152f6ba6d7d 100644
> --- a/drivers/media/platform/ti/j721e-csi2rx/j721e-csi2rx.c
> +++ b/drivers/media/platform/ti/j721e-csi2rx/j721e-csi2rx.c
> @@ -909,10 +909,7 @@ static int ti_csi2rx_get_vc_and_dt(struct ti_csi2rx_ctx *ctx)
>  {
>  	struct ti_csi2rx_dev *csi = ctx->csi;
>  	struct ti_csi2rx_ctx *curr_ctx;
> -	struct v4l2_mbus_frame_desc fd;
>  	struct media_pad *source_pad;
> -	const struct ti_csi2rx_fmt *fmt;
> -	int ret;
>  	unsigned int i, j;
>
>  	/* Get the frame desc from source */
> @@ -920,20 +917,15 @@ static int ti_csi2rx_get_vc_and_dt(struct ti_csi2rx_ctx *ctx)
>  	if (IS_ERR(source_pad))
>  		return PTR_ERR(source_pad);
>
> -	ret = v4l2_subdev_call(csi->source, pad, get_frame_desc, source_pad->index, &fd);
> -	if (ret) {
> -		if (ret == -ENOIOCTLCMD) {
> -			ctx->vc = 0;
> -			fmt = find_format_by_fourcc(ctx->v_fmt.fmt.pix.pixelformat);
> -			ctx->dt = fmt->csi_dt;
> -		}
> -		return ret;
> -	}
> -
> -	if (fd.type != V4L2_MBUS_FRAME_DESC_TYPE_CSI2)
> -		return -EINVAL;
> +	struct v4l2_mbus_frame_desc *fd __free(v4l2_subdev_free_frame_desc) =
> +		v4l2_subdev_get_frame_desc(csi->source, source_pad->index,
> +					   V4L2_MBUS_FRAME_DESC_TYPE_CSI2);
> +	if (IS_ERR(fd))
> +		return PTR_ERR(fd);
>
>  	for (i = 0; i < csi->num_ctx; i++) {
> +		int ret;
> +
>  		curr_ctx = &csi->ctx[i];
>
>  		/* Capture VC 0 by default */
> @@ -943,15 +935,15 @@ static int ti_csi2rx_get_vc_and_dt(struct ti_csi2rx_ctx *ctx)
>  		if (ret)
>  			continue;
>
> -		for (j = 0; j < fd.num_entries; j++) {
> -			if (curr_ctx->stream == fd.entry[j].stream) {
> -				curr_ctx->vc = fd.entry[j].bus.csi2.vc;
> -				curr_ctx->dt = fd.entry[j].bus.csi2.dt;
> +		for (j = 0; j < fd->num_entries; j++) {
> +			if (curr_ctx->stream == fd->entry[j].stream) {
> +				curr_ctx->vc = fd->entry[j].bus.csi2.vc;
> +				curr_ctx->dt = fd->entry[j].bus.csi2.dt;
>  				break;
>  			}
>
>  			/* Return error if no matching stream found */
> -			if (j == fd.num_entries)
> +			if (j == fd->num_entries)
>  				return -EINVAL;
>  		}
>  	}
> --
> 2.47.3
>

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

* Re: [PATCH v3 28/29] media: v4l2-subdev: Use v4l2_subdev_get_frame_desc() for passthrough
  2026-08-24 21:37   ` Frank Li
@ 2026-08-25  7:34     ` Sakari Ailus
  0 siblings, 0 replies; 67+ messages in thread
From: Sakari Ailus @ 2026-08-25  7:34 UTC (permalink / raw)
  To: Frank Li
  Cc: linux-media, laurent.pinchart, Dave Stevenson, Jacopo Mondi,
	Tomi Valkeinen, Jai Luthra, Mehdi Djait, Mattijs Korpershoek

Hi Frank,

Thank you for the review.

On Mon, Aug 24, 2026 at 05:37:36PM -0400, Frank Li wrote:
> On Mon, Aug 24, 2026 at 03:14:50PM +0300, Sakari Ailus wrote:
> > Call v4l2_subdev_get_frame_desc() to obtain the frame descriptor in
> > __v4l2_subdev_get_frame_desc_passthrough(). This is preferred over calling
> > the get_frame_desc() pad operation directly.
> >
> > Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
> > ---
> >  drivers/media/v4l2-core/v4l2-subdev.c | 34 +++++++++++++--------------
> >  1 file changed, 17 insertions(+), 17 deletions(-)
> >
> > diff --git a/drivers/media/v4l2-core/v4l2-subdev.c b/drivers/media/v4l2-core/v4l2-subdev.c
> > index 8c3c5b6e4ee8..2172bb8313ec 100644
> > --- a/drivers/media/v4l2-core/v4l2-subdev.c
> > +++ b/drivers/media/v4l2-core/v4l2-subdev.c
> > @@ -2558,6 +2558,7 @@ int __v4l2_subdev_get_frame_desc_passthrough(struct v4l2_subdev *sd,
> >  					     unsigned int pad,
> >  					     struct v4l2_mbus_frame_desc *fd)
> >  {
> > +	struct v4l2_mbus_frame_desc *source_fd = NULL;
> 
> why not use auto cleanup like other patches? look like only use in loop
> media_entity_for_each_pad()

That would be doable but I think it's cleaner this way. The recommended
usage of __free() is to declare the variable to be __free()'d to a non-NULL
value where it is needed and we can't do that here as we only find out from
routing whether we need to obtain any frame descriptors (or we could, but
that would involve going through routes twice).

-- 
Kind regards,

Sakari Ailus

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

* Re: [PATCH v3 15/29] media: v4l2-subdev: Return dynamically allocated pass-through routes
  2026-08-24 21:00   ` Frank Li
@ 2026-08-25  7:36     ` Sakari Ailus
  0 siblings, 0 replies; 67+ messages in thread
From: Sakari Ailus @ 2026-08-25  7:36 UTC (permalink / raw)
  To: Frank Li
  Cc: linux-media, laurent.pinchart, Dave Stevenson, Jacopo Mondi,
	Tomi Valkeinen, Jai Luthra, Mehdi Djait, Mattijs Korpershoek

Hi Frank,

On Mon, Aug 24, 2026 at 05:00:16PM -0400, Frank Li wrote:
> On Mon, Aug 24, 2026 at 03:14:37PM +0300, Sakari Ailus wrote:
> > Count the number of pass-through routes, allocate memory and then return
> > the full table to the caller.
> >
> > Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
> > ---
> >  drivers/media/v4l2-core/v4l2-subdev.c | 61 +++++++++++++++++++++++----
> >  1 file changed, 52 insertions(+), 9 deletions(-)
> >
> > diff --git a/drivers/media/v4l2-core/v4l2-subdev.c b/drivers/media/v4l2-core/v4l2-subdev.c
> > index c9f38b0313eb..d34704aad88e 100644
> > --- a/drivers/media/v4l2-core/v4l2-subdev.c
> > +++ b/drivers/media/v4l2-core/v4l2-subdev.c
> > @@ -2561,13 +2561,42 @@ int __v4l2_subdev_get_frame_desc_passthrough(struct v4l2_subdev *sd,
> >  	struct media_pad *local_sink_pad;
> >  	struct v4l2_subdev_route *route;
> >  	struct device *dev = sd->dev;
> > -	int ret = 0;
> > +	unsigned int num_entries = 0;
> > +	int ret;
> >
> >  	lockdep_assert_held(state->lock);
> >
> >  	if (WARN_ON(!(sd->entity.pads[pad].flags & MEDIA_PAD_FL_SOURCE)))
> >  		return -EINVAL;
> >
> > +	/* Count the number of entries first */
> > +	media_entity_for_each_pad(&sd->entity, local_sink_pad) {
> > +		if (!(local_sink_pad->flags & MEDIA_PAD_FL_SINK))
> > +			continue;
> > +
> > +		for_each_active_route(&state->routing, route) {
> > +			if (route->source_pad != pad ||
> > +			    route->sink_pad != local_sink_pad->index)
> > +				continue;
> > +
> > +			num_entries++;
> > +
> > +			if (num_entries > V4L2_FRAME_DESC_ENTRY_MAX)
> > +				return -E2BIG;
> > +		}
> > +	}
> > +
> > +	if (num_entries > V4L2_FRAME_DESC_ENTRY_MAX)
> > +		return -E2BIG;
> > +
> > +	if (num_entries > V4L2_FRAME_DESC_ENTRY_PREALLOC) {
> > +		fd->entry = kzalloc_objs(*fd->entry, num_entries, GFP_KERNEL);
> 
> nit: Default should be GFP_KERNEL, needn't GFP_KERNEL when call kzalloc_objs()

I'll drop that in v4.

> 
> Reviewed-by: Frank Li <Frank.Li@nxp.com>

Thank you.

-- 
Regards,

Sakari Ailus

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

* Re: [PATCH v3 17/29] media: bcm2835-unicam: Use v4l2_subdev_get_frame_desc()
  2026-08-24 21:07   ` Frank Li
@ 2026-08-25  7:40     ` Sakari Ailus
  0 siblings, 0 replies; 67+ messages in thread
From: Sakari Ailus @ 2026-08-25  7:40 UTC (permalink / raw)
  To: Frank Li
  Cc: linux-media, laurent.pinchart, Dave Stevenson, Jacopo Mondi,
	Tomi Valkeinen, Jai Luthra, Mehdi Djait, Mattijs Korpershoek

Hi Frank,

On Mon, Aug 24, 2026 at 05:07:46PM -0400, Frank Li wrote:
> On Mon, Aug 24, 2026 at 03:14:39PM +0300, Sakari Ailus wrote:
> > Call v4l2_subdev_get_frame_desc() to obtain the frame descriptor. This is
> > preferred over calling the get_frame_desc() pad operation directly.
> >
> > Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
> > ---
> >  .../media/platform/broadcom/bcm2835-unicam.c  | 22 +++++++++----------
> >  1 file changed, 10 insertions(+), 12 deletions(-)
> >
> > diff --git a/drivers/media/platform/broadcom/bcm2835-unicam.c b/drivers/media/platform/broadcom/bcm2835-unicam.c
> > index 14bb916dd7b1..2322d3df3915 100644
> > --- a/drivers/media/platform/broadcom/bcm2835-unicam.c
> > +++ b/drivers/media/platform/broadcom/bcm2835-unicam.c
> > @@ -27,6 +27,7 @@
> >   * output interface and V4L2 subdevice driver.
> >   */
> >
> > +#include <linux/cleanup.h>
> >  #include <linux/clk.h>
> >  #include <linux/delay.h>
> >  #include <linux/device.h>
> > @@ -888,7 +889,6 @@ static int unicam_get_image_vc_dt(struct unicam_device *unicam,
> >  				  struct v4l2_subdev_state *state,
> >  				  u8 *vc, u8 *dt)
> >  {
> > -	struct v4l2_mbus_frame_desc fd;
> >  	u32 stream;
> >  	int ret;
> >
> > @@ -898,17 +898,15 @@ static int unicam_get_image_vc_dt(struct unicam_device *unicam,
> >  	if (ret)
> >  		return ret;
> >
> > -	ret = v4l2_subdev_call(unicam->sensor.subdev, pad, get_frame_desc,
> > -			       unicam->sensor.pad->index, &fd);
> > -	if (ret)
> > -		return ret;
> > -
> > -	/* Only CSI-2 supports DTs. */
> > -	if (fd.type != V4L2_MBUS_FRAME_DESC_TYPE_CSI2)
> > -		return -EINVAL;
> > +	struct v4l2_mbus_frame_desc *fd __free(v4l2_subdev_free_frame_desc) =
> > +		v4l2_subdev_get_frame_desc(unicam->sensor.subdev,
> > +					   unicam->sensor.pad->index,
> > +					   V4L2_MBUS_FRAME_DESC_TYPE_CSI2);
> > +	if (IS_ERR(fd))
> > +		return PTR_ERR(fd);
> >
> > -	for (unsigned int i = 0; i < fd.num_entries; ++i) {
> > -		const struct v4l2_mbus_frame_desc_entry *fde = &fd.entry[i];
> > +	for (unsigned int i = 0; i < fd->num_entries; ++i) {
> > +		const struct v4l2_mbus_frame_desc_entry *fde = &fd->entry[i];
> >
> >  		if (fde->stream == stream) {
> >  			*vc = fde->bus.csi2.vc;
> > @@ -927,7 +925,7 @@ static void unicam_start_rx(struct unicam_device *unicam,
> >  	const struct unicam_format_info *fmtinfo;
> >  	const struct v4l2_mbus_framefmt *fmt;
> >  	unsigned int line_int_freq;
> > -	u8 vc, dt;
> > +	u8 vc = 0, dt = 0;
> 
> not sure why need here,
> 
> if unicam_get_image_vc_dt() return failure, vc will be set to 0
> if unicam_get_image_vc_dt() return success, vc will be expected value.

You're right -- this chunk can be dropped.

-- 
Sakari Ailus

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

* Re: [PATCH v3 24/29] media: ti: cal: Use v4l2_subdev_get_frame_desc()
  2026-08-24 21:26   ` Frank Li
@ 2026-08-25  8:05     ` Sakari Ailus
  0 siblings, 0 replies; 67+ messages in thread
From: Sakari Ailus @ 2026-08-25  8:05 UTC (permalink / raw)
  To: Frank Li
  Cc: linux-media, laurent.pinchart, Dave Stevenson, Jacopo Mondi,
	Tomi Valkeinen, Jai Luthra, Mehdi Djait, Mattijs Korpershoek

Hi Frank,

On Mon, Aug 24, 2026 at 05:26:04PM -0400, Frank Li wrote:
> On Mon, Aug 24, 2026 at 03:14:46PM +0300, Sakari Ailus wrote:
> > Call v4l2_subdev_get_frame_desc() to obtain the frame descriptor. This is
> > preferred over calling the get_frame_desc() pad operation directly.
> >
> > Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
> > ---
> >  drivers/media/platform/ti/cal/cal-camerarx.c | 26 +++++------
> >  drivers/media/platform/ti/cal/cal.c          | 49 ++++++--------------
> >  2 files changed, 27 insertions(+), 48 deletions(-)
> >
> > diff --git a/drivers/media/platform/ti/cal/cal-camerarx.c b/drivers/media/platform/ti/cal/cal-camerarx.c
> > index 00a71dac0ff4..9ea1f3551d22 100644
> > --- a/drivers/media/platform/ti/cal/cal-camerarx.c
> > +++ b/drivers/media/platform/ti/cal/cal-camerarx.c
> > @@ -9,6 +9,7 @@
> >   *	Laurent Pinchart <laurent.pinchart@ideasonboard.com>
> >   */
> >
> > +#include <linux/cleanup.h>
> >  #include <linux/clk.h>
> >  #include <linux/delay.h>
> >  #include <linux/mfd/syscon.h>
> > @@ -872,7 +873,8 @@ static int cal_camerarx_get_frame_desc(struct v4l2_subdev *sd, unsigned int pad,
> >  				       struct v4l2_mbus_frame_desc *fd)
> >  {
> >  	struct cal_camerarx *phy = to_cal_camerarx(sd);
> > -	struct v4l2_mbus_frame_desc remote_desc;
> > +	struct v4l2_mbus_frame_desc *remote_desc
> > +		__free(v4l2_subdev_free_frame_desc) = NULL;
> >  	const struct media_pad *remote_pad;
> >  	struct v4l2_subdev_state *state;
> >  	u32 sink_stream;
> > @@ -893,24 +895,20 @@ static int cal_camerarx_get_frame_desc(struct v4l2_subdev *sd, unsigned int pad,
> >  		goto out_unlock;
> >  	}
> >
> > -	ret = v4l2_subdev_call(phy->source, pad, get_frame_desc,
> > -			       remote_pad->index, &remote_desc);
> > -	if (ret)
> > -		goto out_unlock;
> > -
> > -	if (remote_desc.type != V4L2_MBUS_FRAME_DESC_TYPE_CSI2) {
> > -		cal_err(phy->cal,
> > -			"Frame descriptor does not describe CSI-2 link");
> > -		ret = -EINVAL;
> > +	remote_desc =
> 
> cleanup prefer declean variable here
> 	struct v4l2_mbus_frame_desc *remote_desc __free(v4l2_subdev_free_frame_desc)
> 		=

Interestingly, that produces the following warning:

In file included from ./include/linux/cleanup.h:6,
                 from drivers/media/platform/ti/cal/cal-camerarx.c:12:
In function ‘IS_ERR_OR_NULL’,
    inlined from ‘__free_v4l2_subdev_free_frame_desc’ at ./include/media/v4l2-subdev.h:1867:1,
    inlined from ‘cal_camerarx_get_frame_desc’ at drivers/media/platform/ti/cal/cal-camerarx.c:896:31:
./include/linux/err.h:92:31: warning: ‘remote_desc’ may be used uninitialized [-Wmaybe-uninitialized]
   92 |         return unlikely(!ptr) || IS_ERR_VALUE((unsigned long)ptr);
drivers/media/platform/ti/cal/cal-camerarx.c: In function ‘cal_camerarx_get_frame_desc’:
drivers/media/platform/ti/cal/cal-camerarx.c:896:38: note: ‘remote_desc’ was declared here
  896 |         struct v4l2_mbus_frame_desc *remote_desc
      |                                      ^~~~~~~~~~~

My guess is that the gotos before the assignment that are the problem.

-- 
Sakari Ailus

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

* Re: [PATCH v3 29/29] media: j721e-csi2rx: Use v4l2_subdev_get_frame_desc()
  2026-08-24 12:14 ` [PATCH v3 29/29] media: j721e-csi2rx: Use v4l2_subdev_get_frame_desc() Sakari Ailus
  2026-08-24 21:38   ` Frank Li
@ 2026-08-26  6:36   ` Jai Luthra
  1 sibling, 0 replies; 67+ messages in thread
From: Jai Luthra @ 2026-08-26  6:36 UTC (permalink / raw)
  To: Sakari Ailus, linux-media
  Cc: laurent.pinchart, Dave Stevenson, Jacopo Mondi, Tomi Valkeinen,
	Mehdi Djait, Mattijs Korpershoek

Quoting Sakari Ailus (2026-08-24 17:44:51)
> Call v4l2_subdev_get_frame_desc() to obtain the frame descriptor. This is
> preferred over calling the get_frame_desc() pad operation directly.
> 
> Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>

Reviewed-by: Jai Luthra <jai.luthra@ideasonboard.com>

Thanks,
    Jai

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

* Re: [PATCH v3 27/29] media: cdns-csi2rc: Use v4l2_subdev_get_frame_desc()
  2026-08-24 12:14 ` [PATCH v3 27/29] media: cdns-csi2rc: " Sakari Ailus
  2026-08-24 21:29   ` Frank Li
@ 2026-08-26  6:39   ` Jai Luthra
  1 sibling, 0 replies; 67+ messages in thread
From: Jai Luthra @ 2026-08-26  6:39 UTC (permalink / raw)
  To: Sakari Ailus, linux-media
  Cc: laurent.pinchart, Dave Stevenson, Jacopo Mondi, Tomi Valkeinen,
	Mehdi Djait, Mattijs Korpershoek

Hi Sakari,

Quoting Sakari Ailus (2026-08-24 17:44:49)
> Call v4l2_subdev_get_frame_desc() to obtain the frame descriptor. This is
> preferred over calling the get_frame_desc() pad operation directly.
> 
> Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>

> Subject: [PATCH v3 27/29] media: cdns-csi2rc: Use v4l2_subdev_get_frame_desc()

s/csi2rc/csi2rx

With that fixed,

Reviewed-by: Jai Luthra <jai.luthra@ideasonboard.com>

Thanks,
    Jai

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

* Re: [PATCH v3 13/29] media: cdn-csi2rc: media: Use v4l2_subdev_get_frame_desc_passthrough_csi2()
  2026-08-24 12:14 ` [PATCH v3 13/29] media: cdn-csi2rc: media: " Sakari Ailus
  2026-08-24 20:47   ` Frank Li
@ 2026-08-26  6:41   ` Jai Luthra
  1 sibling, 0 replies; 67+ messages in thread
From: Jai Luthra @ 2026-08-26  6:41 UTC (permalink / raw)
  To: Sakari Ailus, linux-media
  Cc: laurent.pinchart, Dave Stevenson, Jacopo Mondi, Tomi Valkeinen,
	Mehdi Djait, Mattijs Korpershoek

Quoting Sakari Ailus (2026-08-24 17: 44:35)
> [PATCH v3 13/29] media: cdn-csi2rc: media: Use v4l2_subdev_get_frame_desc_passthrough_csi2()

s/cdn-csi2rc/cdns-csi2rx

With that,
Reviewed-by: Jai Luthra <jai.luthra@ideasonboard.com>

Thanks,
    Jai

> Switch to v4l2_subdev_get_frame_desc_passthrough_csi2() in order to allow
> compatibility with drivers that do not implement get_frame_desc() pad op.
> 
> Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
> ---
>  drivers/media/platform/cadence/cdns-csi2rx.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/media/platform/cadence/cdns-csi2rx.c b/drivers/media/platform/cadence/cdns-csi2rx.c
> index 1ff2d8f78d5b..e31cdcd9ce8e 100644
> --- a/drivers/media/platform/cadence/cdns-csi2rx.c
> +++ b/drivers/media/platform/cadence/cdns-csi2rx.c
> @@ -722,7 +722,7 @@ static const struct v4l2_subdev_pad_ops csi2rx_pad_ops = {
>         .enum_mbus_code         = csi2rx_enum_mbus_code,
>         .get_fmt                = v4l2_subdev_get_fmt,
>         .set_fmt                = csi2rx_set_fmt,
> -       .get_frame_desc         = v4l2_subdev_get_frame_desc_passthrough,
> +       .get_frame_desc         = v4l2_subdev_get_frame_desc_passthrough_csi2,
>         .set_routing            = csi2rx_set_routing,
>         .enable_streams         = csi2rx_enable_streams,
>         .disable_streams        = csi2rx_disable_streams,
> -- 
> 2.47.3
>

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

* Re: [PATCH v3 00/29] Rework frame descriptors
  2026-08-24 12:14 [PATCH v3 00/29] Rework frame descriptors Sakari Ailus
                   ` (28 preceding siblings ...)
  2026-08-24 12:14 ` [PATCH v3 29/29] media: j721e-csi2rx: Use v4l2_subdev_get_frame_desc() Sakari Ailus
@ 2026-08-26  9:58 ` Mattijs Korpershoek
  29 siblings, 0 replies; 67+ messages in thread
From: Mattijs Korpershoek @ 2026-08-26  9:58 UTC (permalink / raw)
  To: Sakari Ailus, linux-media
  Cc: laurent.pinchart, Dave Stevenson, Jacopo Mondi, Tomi Valkeinen,
	Jai Luthra, Mehdi Djait

Hi Sakari,

Thank you for the series.

On Mon, Aug 24, 2026 at 15:14, Sakari Ailus <sakari.ailus@linux.intel.com> wrote:

> Hi folks,
>
> This smallish set makes frame descriptors dynamically allocated and
> implements a single-entry frame descriptor based on the device's format,
> using a new helper called v4l2_subdev_get_frame_desc(). All drivers that
> do not obtain their frame descriptor from upstream are converted. The
> helper also obtains a frame descriptor for the desired type (parallel or
> CSI-2) and checks there's at least one entry there. These checks are
> removed from drivers that currently perform them. (Some drivers also check
> there's exactly a single frame descriptor entry but I think in most cases
> this check could be loosened. That could be done after this set.)
>
> More formats can be added to df-to-mbus conversion as needed. These are
> meant to be initial formats that are enough for typical raw sensors (and
> one RGB format, too).
>
> In the long run this information should probably reside in sub-device
> state. This set however avoids having all receiver drivers to work with
> sub-device drivers (~ 100 of such exist) that have a single stream and so
> do not implement get_frame_desc() op.

With this series, I could sucessfully run a capture using a TI AM69-SK
with the Arducam FPD V3Link[1] using the following device tree overlays:
    ti/k3-am68-sk-v3link-fusion.dtbo ti/k3-v3link-imx219-0-0.dtbo

(See TI's doc [2] for the device tree overlays)

root@am69-sk:~# yavta --capture=10 --file='capture-#-srggb8.bin' --size 1920x1080 --format SRGGB8 /dev/video4
Device /dev/video4 opened.
Device `j721e-csi2rx' on `platform:4500000.ticsi2rx' (driver 'j721e-csi2rx') supports video, capture, without mplanes.
Video format set: SRGGB8 (42474752) 1920x1080 (stride 1920) field none buffer size 2073600
Video format: SRGGB8 (42474752) 1920x1080 (stride 1920) field none buffer size 2073600
8 buffers requested.
length: 2073600 offset: 0 timestamp type/source: mono/EoF
Buffer 0/0 mapped at address 0xffff86a55000.
length: 2073600 offset: 32768 timestamp type/source: mono/EoF
Buffer 1/0 mapped at address 0xffff8685a000.
length: 2073600 offset: 65536 timestamp type/source: mono/EoF
Buffer 2/0 mapped at address 0xffff8665f000.
length: 2073600 offset: 98304 timestamp type/source: mono/EoF
Buffer 3/0 mapped at address 0xffff86464000.
length: 2073600 offset: 131072 timestamp type/source: mono/EoF
Buffer 4/0 mapped at address 0xffff86269000.
length: 2073600 offset: 163840 timestamp type/source: mono/EoF
Buffer 5/0 mapped at address 0xffff8606e000.
length: 2073600 offset: 196608 timestamp type/source: mono/EoF
Buffer 6/0 mapped at address 0xffff85e73000.
length: 2073600 offset: 229376 timestamp type/source: mono/EoF
Buffer 7/0 mapped at address 0xffff85c78000.
0 (0) [-] any 0 2073600 B 105.308050 105.308081 11.612 fps ts mono/EoF
1 (1) [-] any 1 2073600 B 105.341380 105.341435 30.003 fps ts mono/EoF
2 (2) [-] any 2 2073600 B 105.374708 105.374764 30.005 fps ts mono/EoF
3 (3) [-] any 3 2073600 B 105.408031 105.408079 30.009 fps ts mono/EoF
4 (4) [-] any 4 2073600 B 105.441357 105.441394 30.007 fps ts mono/EoF
5 (5) [-] any 5 2073600 B 105.474683 105.474721 30.007 fps ts mono/EoF
6 (6) [-] any 6 2073600 B 105.508009 105.508037 30.007 fps ts mono/EoF
7 (7) [-] any 7 2073600 B 105.541334 105.541368 30.008 fps ts mono/EoF
8 (0) [-] any 8 2073600 B 105.574664 105.574707 30.003 fps ts mono/EoF
9 (1) [-] any 9 2073600 B 105.607990 105.608044 30.007 fps ts mono/EoF
Captured 10 frames in 0.386114 seconds (25.899081 fps, 53704334.562154 B/s).
8 buffers released.

Base: commit 56c29fa3ee66 ("media: rzg2l-cru: Align bytesperline to hardware DMA stride requirement")

Tested-by: Mattijs Korpershoek <mkorpershoek@kernel.org> # am69-sk

[1] https://www.arducam.com/arducam-v3link-camera-kit-for-ti-development-boards.html
[2] https://software-dl.ti.com/jacinto7/esd/processor-sdk-linux-am69/11_00_10_01/exports/docs/linux/Foundational_Components/Kernel/Kernel_Drivers/Camera/CSI2RX.html


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

* Re: [PATCH v3 18/29] media: bcm2835-unicam: Remove frame descriptor workaround
  2026-08-24 21:10   ` Frank Li
@ 2026-08-26 12:09     ` Sakari Ailus
  0 siblings, 0 replies; 67+ messages in thread
From: Sakari Ailus @ 2026-08-26 12:09 UTC (permalink / raw)
  To: Frank Li
  Cc: linux-media, laurent.pinchart, Dave Stevenson, Jacopo Mondi,
	Tomi Valkeinen, Jai Luthra, Mehdi Djait, Mattijs Korpershoek

Hi Frank,

On Mon, Aug 24, 2026 at 05:10:13PM -0400, Frank Li wrote:
> On Mon, Aug 24, 2026 at 03:14:40PM +0300, Sakari Ailus wrote:
> > As the v4l2_subdev_get_frame_desc() either returns a frame descriptor or
> > returns an error, remove the workaround for drivers that didn't implement
> > the get_frame_desc() pad op. Also handle v4l2_subdev_get_frame_desc()
> > errors.
> >
> > Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
> > ---
> >  .../media/platform/broadcom/bcm2835-unicam.c  | 26 +++++++++----------
> >  1 file changed, 12 insertions(+), 14 deletions(-)
> >
> > diff --git a/drivers/media/platform/broadcom/bcm2835-unicam.c b/drivers/media/platform/broadcom/bcm2835-unicam.c
> > index 2322d3df3915..ba613966c333 100644
> > --- a/drivers/media/platform/broadcom/bcm2835-unicam.c
> > +++ b/drivers/media/platform/broadcom/bcm2835-unicam.c
> > @@ -918,8 +918,8 @@ static int unicam_get_image_vc_dt(struct unicam_device *unicam,
> >  	return -EINVAL;
> >  }
> >
> > -static void unicam_start_rx(struct unicam_device *unicam,
> > -			    struct v4l2_subdev_state *state)
> > +static int unicam_start_rx(struct unicam_device *unicam,
> > +			   struct v4l2_subdev_state *state)
> >  {
> >  	struct unicam_node *node = &unicam->node[UNICAM_IMAGE_NODE];
> >  	const struct unicam_format_info *fmtinfo;
> > @@ -933,7 +933,11 @@ static void unicam_start_rx(struct unicam_device *unicam,
> >  	fmtinfo = unicam_find_format_by_code(fmt->code,
> >  					     UNICAM_SD_PAD_SOURCE_IMAGE);
> >  	if (WARN_ON(!fmtinfo))
> > -		return;
> > +		return -EINVAL;
> > +
> > +	ret = unicam_get_image_vc_dt(unicam, state, &vc, &dt);
> > +	if (ret)
> > +		return ret;
> >
> >  	/*
> >  	 * Enable lane clocks. The register is structured as follows:
> > @@ -1090,16 +1094,6 @@ static void unicam_start_rx(struct unicam_device *unicam,
> >  	unicam_wr_dma_addr(node, node->cur_frm);
> >  	unicam_set_packing_config(unicam, fmtinfo);
> >
> > -	ret = unicam_get_image_vc_dt(unicam, state, &vc, &dt);
> > -	if (ret) {
> > -		/*
> > -		 * If the source doesn't support frame descriptors, default to
> > -		 * VC 0 and use the DT corresponding to the format.
> > -		 */
> > -		vc = 0;
> > -		dt = fmtinfo->csi_dt;
> > -	}
> > -
> 
> look likes vc=0, dt=0 change in patch 17 should be in this patch?

It seems like that, yes. The compilers aren't smart enough to figure out
they're not used when not set.

-- 
Sakari Ailus

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

* Re: [PATCH v3 01/29] media: v4l2-common: Add helper function media_bus_fmt_to_csi2_(bpp|dt)()
  2026-08-24 12:14 ` [PATCH v3 01/29] media: v4l2-common: Add helper function media_bus_fmt_to_csi2_(bpp|dt)() Sakari Ailus
@ 2026-08-26 13:18   ` Linus Walleij
  2026-08-27  7:45     ` Linus Walleij
  2026-08-27  8:50     ` Sakari Ailus
  2026-08-27 22:29   ` Linus Walleij
  1 sibling, 2 replies; 67+ messages in thread
From: Linus Walleij @ 2026-08-26 13:18 UTC (permalink / raw)
  To: Sakari Ailus
  Cc: linux-media, laurent.pinchart, Dave Stevenson, Jacopo Mondi,
	Tomi Valkeinen, Jai Luthra, Mehdi Djait, Mattijs Korpershoek

Hi Sakari,

(long time no see!)

thanks for your patch!

On Mon, Aug 24, 2026 at 2:14 PM Sakari Ailus
<sakari.ailus@linux.intel.com> wrote:


> +struct media_bus_fmt_info {
> +       u32 code;

Nit: maybe call this .bus_fmt instead?

> +       u8 dt;
> +       u8 bpp;
> +};
(...)
> +       { .code = MEDIA_BUS_FMT_RGB444_1X12, .bpp = 12 },

Some of these are just code + bpp

> +       { .code = MEDIA_BUS_FMT_RGB565_1X16, .dt = MIPI_CSI2_DT_RGB565, .bpp = 16 },

and some also have data type (dt)

So here:

> +int media_bus_fmt_to_csi2_dt(u32 bus_fmt)
> +{
> +       const struct media_bus_fmt_info *info = media_bus_fmt_info_get(bus_fmt);

This will find entries as long as we find the bus format .code

> +       if (!info)
> +               return -EINVAL;

and bail out if it doesn't, but:

> +       /* Check bpp because 0 (MIPI_CSI2_DT_FS) is a valid data type code */
> +       return info->bpp ? info->dt : -EINVAL;


As long as it's found, it will return info->dt even for e.g.:

{ .code = MEDIA_BUS_FMT_RGB444_1X12, .bpp = 12 },

this will result in the zero-initialized data type 0x00
which is (I think) frame start?

So maybe

if (!info || !info->dt)
    return NULL;

Yours,
Linus Walleij

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

* Re: [PATCH v3 01/29] media: v4l2-common: Add helper function media_bus_fmt_to_csi2_(bpp|dt)()
  2026-08-26 13:18   ` Linus Walleij
@ 2026-08-27  7:45     ` Linus Walleij
  2026-08-27  8:50     ` Sakari Ailus
  1 sibling, 0 replies; 67+ messages in thread
From: Linus Walleij @ 2026-08-27  7:45 UTC (permalink / raw)
  To: Sakari Ailus
  Cc: linux-media, laurent.pinchart, Dave Stevenson, Jacopo Mondi,
	Tomi Valkeinen, Jai Luthra, Mehdi Djait, Mattijs Korpershoek

On Wed, Aug 26, 2026 at 3:18 PM Linus Walleij <linusw@kernel.org> wrote:

> So maybe
>
> if (!info || !info->dt)
>     return NULL;

Eh
return -EINVAL;

obviously.

Yours,
Linus Walleij

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

* Re: [PATCH v3 02/29] media: v4l2-subdev: Align frame descriptor error codes with routing
  2026-08-24 12:14 ` [PATCH v3 02/29] media: v4l2-subdev: Align frame descriptor error codes with routing Sakari Ailus
@ 2026-08-27  7:46   ` Linus Walleij
  0 siblings, 0 replies; 67+ messages in thread
From: Linus Walleij @ 2026-08-27  7:46 UTC (permalink / raw)
  To: Sakari Ailus
  Cc: linux-media, laurent.pinchart, Dave Stevenson, Jacopo Mondi,
	Tomi Valkeinen, Jai Luthra, Mehdi Djait, Mattijs Korpershoek

On Mon, Aug 24, 2026 at 2:14 PM Sakari Ailus
<sakari.ailus@linux.intel.com> wrote:

> __v4l2_subdev_get_frame_desc_passthrough() returns -ENOSPC when there are
> too many routes. There's a subtle difference when compared to -E2BIG, but
> -E2BIG can be used in this case as well. In practice this was unlikely to
> having been ever returned from the kernel as things currently stand.
>
> Align the error codes with the routing IOCTLs.
>
> Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
> Reviewed-by: Frank Li <Frank.Li@nxp.com>

Reviewed-by: Linus Walleij <linusw@kernel.org>

Yours,
Linus Walleij

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

* Re: [PATCH v3 01/29] media: v4l2-common: Add helper function media_bus_fmt_to_csi2_(bpp|dt)()
  2026-08-26 13:18   ` Linus Walleij
  2026-08-27  7:45     ` Linus Walleij
@ 2026-08-27  8:50     ` Sakari Ailus
  2026-08-27  9:34       ` Sakari Ailus
  1 sibling, 1 reply; 67+ messages in thread
From: Sakari Ailus @ 2026-08-27  8:50 UTC (permalink / raw)
  To: Linus Walleij
  Cc: linux-media, laurent.pinchart, Dave Stevenson, Jacopo Mondi,
	Tomi Valkeinen, Jai Luthra, Mehdi Djait, Mattijs Korpershoek

Hi Linus,

On Wed, Aug 26, 2026 at 03:18:11PM +0200, Linus Walleij wrote:
> Hi Sakari,
> 
> (long time no see!)

Indeed!

> 
> thanks for your patch!

And thank you for the review! :-)

> 
> On Mon, Aug 24, 2026 at 2:14 PM Sakari Ailus
> <sakari.ailus@linux.intel.com> wrote:
> 
> 
> > +struct media_bus_fmt_info {
> > +       u32 code;
> 
> Nit: maybe call this .bus_fmt instead?

Good question. The pixel codes are indeed called codes, not formats in this
context, but the struct name contains "fmt" which implies size as well as
other information could be included but there isn't any.

Instead I think I'd call this media_bus_code_info in fact.

> 
> > +       u8 dt;
> > +       u8 bpp;
> > +};
> (...)
> > +       { .code = MEDIA_BUS_FMT_RGB444_1X12, .bpp = 12 },
> 
> Some of these are just code + bpp
> 
> > +       { .code = MEDIA_BUS_FMT_RGB565_1X16, .dt = MIPI_CSI2_DT_RGB565, .bpp = 16 },
> 
> and some also have data type (dt)
> 
> So here:
> 
> > +int media_bus_fmt_to_csi2_dt(u32 bus_fmt)
> > +{
> > +       const struct media_bus_fmt_info *info = media_bus_fmt_info_get(bus_fmt);
> 
> This will find entries as long as we find the bus format .code
> 
> > +       if (!info)
> > +               return -EINVAL;
> 
> and bail out if it doesn't, but:
> 
> > +       /* Check bpp because 0 (MIPI_CSI2_DT_FS) is a valid data type code */
> > +       return info->bpp ? info->dt : -EINVAL;
> 
> 
> As long as it's found, it will return info->dt even for e.g.:
> 
> { .code = MEDIA_BUS_FMT_RGB444_1X12, .bpp = 12 },
> 
> this will result in the zero-initialized data type 0x00
> which is (I think) frame start?
> 
> So maybe
> 
> if (!info || !info->dt)
>     return NULL;

The check indeed should be for info->dt, not info->bpp. The FS (frame
start) packet is a short packet and short packets aren't associated with
mbus codes so that's a non-issue.

-- 
Kind regards,

Sakari Ailus

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

* Re: [PATCH v3 01/29] media: v4l2-common: Add helper function media_bus_fmt_to_csi2_(bpp|dt)()
  2026-08-27  8:50     ` Sakari Ailus
@ 2026-08-27  9:34       ` Sakari Ailus
  0 siblings, 0 replies; 67+ messages in thread
From: Sakari Ailus @ 2026-08-27  9:34 UTC (permalink / raw)
  To: Linus Walleij
  Cc: linux-media, laurent.pinchart, Dave Stevenson, Jacopo Mondi,
	Tomi Valkeinen, Jai Luthra, Mehdi Djait, Mattijs Korpershoek

On Thu, Aug 27, 2026 at 11:51:00AM +0300, Sakari Ailus wrote:
> Good question. The pixel codes are indeed called codes, not formats in this
> context, but the struct name contains "fmt" which implies size as well as
> other information could be included but there isn't any.
> 
> Instead I think I'd call this media_bus_code_info in fact.

Of course the MEDIA_BUS_FMT_* macros then use FMT again. We can't do this
consistently anymore as it's all in the UAPI. :-o

-- 
Sakari Ailus

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

* Re: [PATCH v3 01/29] media: v4l2-common: Add helper function media_bus_fmt_to_csi2_(bpp|dt)()
  2026-08-24 12:14 ` [PATCH v3 01/29] media: v4l2-common: Add helper function media_bus_fmt_to_csi2_(bpp|dt)() Sakari Ailus
  2026-08-26 13:18   ` Linus Walleij
@ 2026-08-27 22:29   ` Linus Walleij
  1 sibling, 0 replies; 67+ messages in thread
From: Linus Walleij @ 2026-08-27 22:29 UTC (permalink / raw)
  To: Sakari Ailus
  Cc: linux-media, laurent.pinchart, Dave Stevenson, Jacopo Mondi,
	Tomi Valkeinen, Jai Luthra, Mehdi Djait, Mattijs Korpershoek

Hi Sakari/Frank,

one more thing which might be a rookie mistake on my side though:

On Mon, Aug 24, 2026 at 2:14 PM Sakari Ailus
<sakari.ailus@linux.intel.com> wrote:

In this example:

> CSI2 data type is defined by MIPI Camera Serial Interface 2 Spec Ver4.1.
> See section 9.4.
>
> Add helper function media_bus_fmt_to_csi2_dt() to convert media bus fmt to
> MIPI defined data type and avoid below duplicated static array in each CSI2
> drivers.
>
>         {
>                 .code = MEDIA_BUS_FMT_UYVY8_1X16,
>                 .data_type = MIPI_CSI2_DT_YUV422_8B,
>         }

The way I read the CSI-2 spec YUV422 8bit has this byte order: U Y V Y
(this is in section 11.2.4 in my copy of the spec, figure and all)
so this looks correct if you just look at that string: UYVY no problem.

I tried to understand the MEDIA_BUS_FMT_* conventions...
I looked here:
https://docs.kernel.org/next/userspace-api/media/v4l/subdev-formats.html

And in the table in the docs:

Word 1: bit 15..8 is U, bits 7..0 is Y
Word 2: bit 15..8 is V, bits 7..0 is Y

I *think* 1X16 should be understood as 2x16bit words (samples?) where
each 16bit word is in LSB, MSB ("little endian") order, i.. bits 7..0 (Y)
are transmitted *first* then bits 15..8 (U) correct me
if I misunderstood!

Then UYVY8_1X16 becomes the *byte* order Y U Y V.

But YUYV on the other hand becomes U Y V Y !

Isn't this then MEDIA_BUS_FMT_YUYV8_1X16 ?

I'm reading the spec and Linux format codes until my eyes fall out...

It's there in the code though:

> +       { .code = MEDIA_BUS_FMT_UYVY8_1X16, .dt = MIPI_CSI2_DT_YUV422_8B, .bpp = 16 },
> +       { .code = MEDIA_BUS_FMT_VYUY8_1X16, .dt = MIPI_CSI2_DT_YUV422_8B, .bpp = 16 },
> +       { .code = MEDIA_BUS_FMT_YUYV8_1X16, .dt = MIPI_CSI2_DT_YUV422_8B, .bpp = 16 },
> +       { .code = MEDIA_BUS_FMT_YVYU8_1X16, .dt = MIPI_CSI2_DT_YUV422_8B, .bpp = 16 },

all four of the related encodings, I don't know if this works in practice
but it seems off. Three of them must be wrong since MIPI_CSI2_DT_YUV422_8B
is very determined?

Obviously I didn't check the entire table like this, but if there is something
to what I'm saying then we have to...

Yours,
Linus Walleij

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

end of thread, other threads:[~2026-08-27 22:29 UTC | newest]

Thread overview: 67+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-08-24 12:14 [PATCH v3 00/29] Rework frame descriptors Sakari Ailus
2026-08-24 12:14 ` [PATCH v3 01/29] media: v4l2-common: Add helper function media_bus_fmt_to_csi2_(bpp|dt)() Sakari Ailus
2026-08-26 13:18   ` Linus Walleij
2026-08-27  7:45     ` Linus Walleij
2026-08-27  8:50     ` Sakari Ailus
2026-08-27  9:34       ` Sakari Ailus
2026-08-27 22:29   ` Linus Walleij
2026-08-24 12:14 ` [PATCH v3 02/29] media: v4l2-subdev: Align frame descriptor error codes with routing Sakari Ailus
2026-08-27  7:46   ` Linus Walleij
2026-08-24 12:14 ` [PATCH v3 03/29] media: v4l2-subdev: Prepare for changes in getting frame descriptors Sakari Ailus
2026-08-24 12:14 ` [PATCH v3 04/29] media: v4l2-subdev: Allow releasing frame descriptors on return Sakari Ailus
2026-08-24 20:34   ` Frank Li
2026-08-24 12:14 ` [PATCH v3 05/29] media: v4l2-subdev: Allow allocating frame descriptors based on the need Sakari Ailus
2026-08-24 12:14 ` [PATCH v3 06/29] media: v4l2-subdev: Change the maximum number of routes Sakari Ailus
2026-08-24 12:14 ` [PATCH v3 07/29] media: v4l2-subdev: Add frame descriptor passthrough for CSI-2 and DVP Sakari Ailus
2026-08-24 20:43   ` Frank Li
2026-08-24 12:14 ` [PATCH v3 08/29] media: ds90ub913: Use v4l2_subdev_get_frame_desc_passthrough_csi2() Sakari Ailus
2026-08-24 20:44   ` Frank Li
2026-08-24 12:14 ` [PATCH v3 09/29] media: ds90ub953: " Sakari Ailus
2026-08-24 20:44   ` Frank Li
2026-08-24 12:14 ` [PATCH v3 10/29] media: nxp: imx8-isi: " Sakari Ailus
2026-08-24 20:44   ` Frank Li
2026-08-24 12:14 ` [PATCH v3 11/29] media: rzg2l-cru: " Sakari Ailus
2026-08-24 20:45   ` Frank Li
2026-08-24 12:14 ` [PATCH v3 12/29] media: dw-mipi-csi2rx: " Sakari Ailus
2026-08-24 20:46   ` Frank Li
2026-08-24 12:14 ` [PATCH v3 13/29] media: cdn-csi2rc: media: " Sakari Ailus
2026-08-24 20:47   ` Frank Li
2026-08-26  6:41   ` Jai Luthra
2026-08-24 12:14 ` [PATCH v3 14/29] media: v4l2-subdev: Make v4l2_subdev_get_frame_desc_passthrough() static Sakari Ailus
2026-08-24 20:48   ` Frank Li
2026-08-24 12:14 ` [PATCH v3 15/29] media: v4l2-subdev: Return dynamically allocated pass-through routes Sakari Ailus
2026-08-24 21:00   ` Frank Li
2026-08-25  7:36     ` Sakari Ailus
2026-08-24 12:14 ` [PATCH v3 16/29] media: v4l2-subdev: Always return at least one frame descriptor Sakari Ailus
2026-08-24 12:14 ` [PATCH v3 17/29] media: bcm2835-unicam: Use v4l2_subdev_get_frame_desc() Sakari Ailus
2026-08-24 21:07   ` Frank Li
2026-08-25  7:40     ` Sakari Ailus
2026-08-24 12:14 ` [PATCH v3 18/29] media: bcm2835-unicam: Remove frame descriptor workaround Sakari Ailus
2026-08-24 21:10   ` Frank Li
2026-08-26 12:09     ` Sakari Ailus
2026-08-24 12:14 ` [PATCH v3 19/29] media: nxp: imx8-isi: Use v4l2_subdev_get_frame_desc() Sakari Ailus
2026-08-24 12:14 ` [PATCH v3 20/29] media: raspberrypi: cfe: " Sakari Ailus
2026-08-24 21:11   ` Frank Li
2026-08-24 12:14 ` [PATCH v3 21/29] media: rzg2l-cru: " Sakari Ailus
2026-08-24 21:13   ` Frank Li
2026-08-24 12:14 ` [PATCH v3 22/29] media: rkisp1: " Sakari Ailus
2026-08-24 21:13   ` Frank Li
2026-08-24 12:14 ` [PATCH v3 23/29] media: exynos4-is: " Sakari Ailus
2026-08-24 21:22   ` Frank Li
2026-08-24 12:14 ` [PATCH v3 24/29] media: ti: cal: " Sakari Ailus
2026-08-24 21:26   ` Frank Li
2026-08-25  8:05     ` Sakari Ailus
2026-08-24 12:14 ` [PATCH v3 25/29] media: ipu6: " Sakari Ailus
2026-08-24 21:26   ` Frank Li
2026-08-24 12:14 ` [PATCH v3 26/29] staging: media: ipu7: " Sakari Ailus
2026-08-24 21:27   ` Frank Li
2026-08-24 12:14 ` [PATCH v3 27/29] media: cdns-csi2rc: " Sakari Ailus
2026-08-24 21:29   ` Frank Li
2026-08-26  6:39   ` Jai Luthra
2026-08-24 12:14 ` [PATCH v3 28/29] media: v4l2-subdev: Use v4l2_subdev_get_frame_desc() for passthrough Sakari Ailus
2026-08-24 21:37   ` Frank Li
2026-08-25  7:34     ` Sakari Ailus
2026-08-24 12:14 ` [PATCH v3 29/29] media: j721e-csi2rx: Use v4l2_subdev_get_frame_desc() Sakari Ailus
2026-08-24 21:38   ` Frank Li
2026-08-26  6:36   ` Jai Luthra
2026-08-26  9:58 ` [PATCH v3 00/29] Rework frame descriptors Mattijs Korpershoek

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox