All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 00/17] Rework frame descriptors
@ 2026-05-18 16:43 Sakari Ailus
  2026-05-18 16:43 ` [PATCH v2 01/17] media: v4l2-common: Add helper function media_bus_fmt_to_csi2_(bpp|dt)() Sakari Ailus
                   ` (18 more replies)
  0 siblings, 19 replies; 33+ messages in thread
From: Sakari Ailus @ 2026-05-18 16:43 UTC (permalink / raw)
  To: linux-media
  Cc: laurent.pinchart, Dave Stevenson, Jacopo Mondi, Tomi Valkeinen,
	Jai Luthra, Mehdi Djait, Frank Li

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.)

On callee side these patches introduce no changes as the number of
pre-allocated memory for 8 frame descriptors remains as-is. The
get_frame_desc() pad op can return more than 8 frame descriptors by
setting the num_entries to the desired number and returning -ENOSPC.

If people prefer using cleanup.h / __free() to release the dynamically
allocated array (I think I'd almost require that), I'll merge the
now-separate __v4l2_subdev_get_frame_desc() into
v4l2_subdev_get_frame_desc().

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).

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 (16):
  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: Allocate frame descriptors based on the need
  media: v4l2-subdev: Change the maximum number of routes
  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: 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()

 drivers/media/pci/intel/ipu6/ipu6-isys-csi2.c |  22 +--
 .../media/platform/broadcom/bcm2835-unicam.c  |  22 +--
 .../platform/nxp/imx8-isi/imx8-isi-crossbar.c |  19 +-
 .../media/platform/raspberrypi/rp1-cfe/cfe.c  |  28 ++-
 .../platform/renesas/rzg2l-cru/rzg2l-video.c  |  27 +--
 .../platform/rockchip/rkisp1/rkisp1-isp.c     |  21 +-
 .../samsung/exynos4-is/fimc-capture.c         |  18 +-
 drivers/media/platform/ti/cal/cal-camerarx.c  |  26 ++-
 drivers/media/v4l2-core/v4l2-common.c         | 183 ++++++++++++++++++
 drivers/media/v4l2-core/v4l2-subdev.c         | 152 +++++++++++++--
 .../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                   |  78 +++++++-
 14 files changed, 512 insertions(+), 153 deletions(-)

-- 
2.47.3


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

* [PATCH v2 01/17] media: v4l2-common: Add helper function media_bus_fmt_to_csi2_(bpp|dt)()
  2026-05-18 16:43 [PATCH v2 00/17] Rework frame descriptors Sakari Ailus
@ 2026-05-18 16:43 ` Sakari Ailus
  2026-05-18 16:43 ` [PATCH v2 02/17] media: v4l2-subdev: Align frame descriptor error codes with routing Sakari Ailus
                   ` (17 subsequent siblings)
  18 siblings, 0 replies; 33+ messages in thread
From: Sakari Ailus @ 2026-05-18 16:43 UTC (permalink / raw)
  To: linux-media
  Cc: laurent.pinchart, Dave Stevenson, Jacopo Mondi, Tomi Valkeinen,
	Jai Luthra, Mehdi Djait, Frank Li

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>
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 bceafc4e92c8..2bf53799587f 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>
@@ -808,3 +809,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, .bpp = 8 },
+	{ .code = MEDIA_BUS_FMT_META_10, .bpp = 10 },
+	{ .code = MEDIA_BUS_FMT_META_12, .bpp = 12 },
+	{ .code = MEDIA_BUS_FMT_META_14, .bpp = 14 },
+	{ .code = MEDIA_BUS_FMT_META_16, .bpp = 16 },
+	{ .code = MEDIA_BUS_FMT_META_20, .bpp = 20 },
+	{ .code = MEDIA_BUS_FMT_META_24, .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] 33+ messages in thread

* [PATCH v2 02/17] media: v4l2-subdev: Align frame descriptor error codes with routing
  2026-05-18 16:43 [PATCH v2 00/17] Rework frame descriptors Sakari Ailus
  2026-05-18 16:43 ` [PATCH v2 01/17] media: v4l2-common: Add helper function media_bus_fmt_to_csi2_(bpp|dt)() Sakari Ailus
@ 2026-05-18 16:43 ` Sakari Ailus
  2026-05-18 16:43 ` [PATCH v2 03/17] media: v4l2-subdev: Prepare for changes in getting frame descriptors Sakari Ailus
                   ` (16 subsequent siblings)
  18 siblings, 0 replies; 33+ messages in thread
From: Sakari Ailus @ 2026-05-18 16:43 UTC (permalink / raw)
  To: linux-media
  Cc: laurent.pinchart, Dave Stevenson, Jacopo Mondi, Tomi Valkeinen,
	Jai Luthra, Mehdi Djait, Frank Li

__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.

-ENOSPC can be then repurposed for signalling of running out of entries in
the statically allocated array.

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] 33+ messages in thread

* [PATCH v2 03/17] media: v4l2-subdev: Prepare for changes in getting frame descriptors
  2026-05-18 16:43 [PATCH v2 00/17] Rework frame descriptors Sakari Ailus
  2026-05-18 16:43 ` [PATCH v2 01/17] media: v4l2-common: Add helper function media_bus_fmt_to_csi2_(bpp|dt)() Sakari Ailus
  2026-05-18 16:43 ` [PATCH v2 02/17] media: v4l2-subdev: Align frame descriptor error codes with routing Sakari Ailus
@ 2026-05-18 16:43 ` Sakari Ailus
  2026-05-18 16:43 ` [PATCH v2 04/17] media: v4l2-subdev: Allow releasing frame descriptors on return Sakari Ailus
                   ` (15 subsequent siblings)
  18 siblings, 0 replies; 33+ messages in thread
From: Sakari Ailus @ 2026-05-18 16:43 UTC (permalink / raw)
  To: linux-media
  Cc: laurent.pinchart, Dave Stevenson, Jacopo Mondi, Tomi Valkeinen,
	Jai Luthra, Mehdi Djait, Frank Li

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..489c2ba0956f 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)
+{
+	struct v4l2_subdev_format subdev_fmt = {
+		.which = V4L2_SUBDEV_FORMAT_ACTIVE,
+		.pad = pad,
+	};
+	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_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] 33+ messages in thread

* [PATCH v2 04/17] media: v4l2-subdev: Allow releasing frame descriptors on return
  2026-05-18 16:43 [PATCH v2 00/17] Rework frame descriptors Sakari Ailus
                   ` (2 preceding siblings ...)
  2026-05-18 16:43 ` [PATCH v2 03/17] media: v4l2-subdev: Prepare for changes in getting frame descriptors Sakari Ailus
@ 2026-05-18 16:43 ` Sakari Ailus
  2026-05-19 21:34   ` Frank Li
  2026-05-18 16:43 ` [PATCH v2 05/17] media: v4l2-subdev: Allocate frame descriptors based on the need Sakari Ailus
                   ` (14 subsequent siblings)
  18 siblings, 1 reply; 33+ messages in thread
From: Sakari Ailus @ 2026-05-18 16:43 UTC (permalink / raw)
  To: linux-media
  Cc: laurent.pinchart, Dave Stevenson, Jacopo Mondi, Tomi Valkeinen,
	Jai Luthra, Mehdi Djait, Frank Li

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] 33+ messages in thread

* [PATCH v2 05/17] media: v4l2-subdev: Allocate frame descriptors based on the need
  2026-05-18 16:43 [PATCH v2 00/17] Rework frame descriptors Sakari Ailus
                   ` (3 preceding siblings ...)
  2026-05-18 16:43 ` [PATCH v2 04/17] media: v4l2-subdev: Allow releasing frame descriptors on return Sakari Ailus
@ 2026-05-18 16:43 ` Sakari Ailus
  2026-05-19 21:53   ` Frank Li
  2026-05-18 16:43 ` [PATCH v2 06/17] media: v4l2-subdev: Change the maximum number of routes Sakari Ailus
                   ` (13 subsequent siblings)
  18 siblings, 1 reply; 33+ messages in thread
From: Sakari Ailus @ 2026-05-18 16:43 UTC (permalink / raw)
  To: linux-media
  Cc: laurent.pinchart, Dave Stevenson, Jacopo Mondi, Tomi Valkeinen,
	Jai Luthra, Mehdi Djait, Frank Li

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 allocating as much memory as required.
The get_frame_desc() op can now set the num_entries to a number larger
than V4L2_FRAME_BUS_ENTRY_PREALLOC and return -ENOSPC. The caller,
v4l2_subdev_get_frame_desc(), will then allocate memory for that amount of
memory and call the get_frame_desc() op again.

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>
---
 drivers/media/v4l2-core/v4l2-subdev.c | 60 +++++++++++++++++++++------
 include/media/v4l2-subdev.h           | 39 +++++++++++------
 2 files changed, 75 insertions(+), 24 deletions(-)

diff --git a/drivers/media/v4l2-core/v4l2-subdev.c b/drivers/media/v4l2-core/v4l2-subdev.c
index 489c2ba0956f..da8464dfb265 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,41 @@ 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 == -ENOSPC) {
+		if (fd->num_entries <= V4L2_FRAME_DESC_ENTRY_PREALLOC ||
+		    fd->num_entries > V4L2_FRAME_DESC_ENTRY_MAX)
+			return -E2BIG;
+
+		fd->entry = kzalloc_objs(*fd->entry, fd->num_entries,
+					 GFP_KERNEL);
+		if (!fd->entry)
+			return -ENOMEM;
+
+		fd->len_entries = fd->num_entries;
+		fd->num_entries = 0;
+
+		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 +1108,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 +2660,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;
 			}
@@ -2707,6 +2729,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 +2747,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 +2775,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..f9b121eefa92 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,14 @@ 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 num_entries exceeds len_entries, the callback
+ *		    shall return -ENOSPC. Never call this directly in drivers,
+ *		    use v4l2_subdev_get_frame_desc() instead.
  *
  * @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 +1807,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 +1827,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] 33+ messages in thread

* [PATCH v2 06/17] media: v4l2-subdev: Change the maximum number of routes
  2026-05-18 16:43 [PATCH v2 00/17] Rework frame descriptors Sakari Ailus
                   ` (4 preceding siblings ...)
  2026-05-18 16:43 ` [PATCH v2 05/17] media: v4l2-subdev: Allocate frame descriptors based on the need Sakari Ailus
@ 2026-05-18 16:43 ` Sakari Ailus
  2026-05-19 21:55   ` Frank Li
  2026-05-18 16:43 ` [PATCH v2 07/17] media: v4l2-subdev: Return dynamically allocated pass-through routes Sakari Ailus
                   ` (12 subsequent siblings)
  18 siblings, 1 reply; 33+ messages in thread
From: Sakari Ailus @ 2026-05-18 16:43 UTC (permalink / raw)
  To: linux-media
  Cc: laurent.pinchart, Dave Stevenson, Jacopo Mondi, Tomi Valkeinen,
	Jai Luthra, Mehdi Djait, Frank Li

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>
---
 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 da8464dfb265..ebcc0b40fac1 100644
--- a/drivers/media/v4l2-core/v4l2-subdev.c
+++ b/drivers/media/v4l2-core/v4l2-subdev.c
@@ -1103,14 +1103,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] 33+ messages in thread

* [PATCH v2 07/17] media: v4l2-subdev: Return dynamically allocated pass-through routes
  2026-05-18 16:43 [PATCH v2 00/17] Rework frame descriptors Sakari Ailus
                   ` (5 preceding siblings ...)
  2026-05-18 16:43 ` [PATCH v2 06/17] media: v4l2-subdev: Change the maximum number of routes Sakari Ailus
@ 2026-05-18 16:43 ` Sakari Ailus
  2026-05-19 22:33   ` Frank Li
  2026-05-18 16:43 ` [PATCH v2 08/17] media: v4l2-subdev: Always return at least one frame descriptor Sakari Ailus
                   ` (11 subsequent siblings)
  18 siblings, 1 reply; 33+ messages in thread
From: Sakari Ailus @ 2026-05-18 16:43 UTC (permalink / raw)
  To: linux-media
  Cc: laurent.pinchart, Dave Stevenson, Jacopo Mondi, Tomi Valkeinen,
	Jai Luthra, Mehdi Djait, Frank Li

Count the number of pass-through routes and then return the full table
once enough memory is available for it.

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

diff --git a/drivers/media/v4l2-core/v4l2-subdev.c b/drivers/media/v4l2-core/v4l2-subdev.c
index ebcc0b40fac1..b5eef0baa237 100644
--- a/drivers/media/v4l2-core/v4l2-subdev.c
+++ b/drivers/media/v4l2-core/v4l2-subdev.c
@@ -2653,20 +2653,22 @@ int __v4l2_subdev_get_frame_desc_passthrough(struct v4l2_subdev *sd,
 				return -EPIPE;
 			}
 
-			if (fd->num_entries >= V4L2_FRAME_DESC_ENTRY_PREALLOC) {
+			if (fd->num_entries >= V4L2_FRAME_DESC_ENTRY_MAX) {
 				dev_dbg(dev, "Frame desc entry limit reached\n");
 				return -E2BIG;
 			}
 
-			fd->entry[fd->num_entries] = *source_entry;
-
-			fd->entry[fd->num_entries].stream = route->source_stream;
+			if (fd->num_entries < fd->len_entries) {
+				fd->entry[fd->num_entries] = *source_entry;
+				fd->entry[fd->num_entries].stream =
+					route->source_stream;
+			}
 
 			fd->num_entries++;
 		}
 	}
 
-	return 0;
+	return fd->num_entries < fd->len_entries ? 0 : -ENOSPC;
 }
 EXPORT_SYMBOL_GPL(__v4l2_subdev_get_frame_desc_passthrough);
 
-- 
2.47.3


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

* [PATCH v2 08/17] media: v4l2-subdev: Always return at least one frame descriptor
  2026-05-18 16:43 [PATCH v2 00/17] Rework frame descriptors Sakari Ailus
                   ` (6 preceding siblings ...)
  2026-05-18 16:43 ` [PATCH v2 07/17] media: v4l2-subdev: Return dynamically allocated pass-through routes Sakari Ailus
@ 2026-05-18 16:43 ` Sakari Ailus
  2026-05-19 22:35   ` Frank Li
  2026-05-18 16:43 ` [PATCH v2 09/17] media: bcm2835-unicam: Use v4l2_subdev_get_frame_desc() Sakari Ailus
                   ` (10 subsequent siblings)
  18 siblings, 1 reply; 33+ messages in thread
From: Sakari Ailus @ 2026-05-18 16:43 UTC (permalink / raw)
  To: linux-media
  Cc: laurent.pinchart, Dave Stevenson, Jacopo Mondi, Tomi Valkeinen,
	Jai Luthra, Mehdi Djait, Frank Li

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>
---
 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 b5eef0baa237..dc4ac08c210f 100644
--- a/drivers/media/v4l2-core/v4l2-subdev.c
+++ b/drivers/media/v4l2-core/v4l2-subdev.c
@@ -2732,6 +2732,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 f9b121eefa92..0361c8bbee38 100644
--- a/include/media/v4l2-subdev.h
+++ b/include/media/v4l2-subdev.h
@@ -1817,6 +1817,8 @@ int v4l2_subdev_get_frame_desc_passthrough(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] 33+ messages in thread

* [PATCH v2 09/17] media: bcm2835-unicam: Use v4l2_subdev_get_frame_desc()
  2026-05-18 16:43 [PATCH v2 00/17] Rework frame descriptors Sakari Ailus
                   ` (7 preceding siblings ...)
  2026-05-18 16:43 ` [PATCH v2 08/17] media: v4l2-subdev: Always return at least one frame descriptor Sakari Ailus
@ 2026-05-18 16:43 ` Sakari Ailus
  2026-05-18 16:43 ` [PATCH v2 10/17] media: nxp: imx8-isi: " Sakari Ailus
                   ` (9 subsequent siblings)
  18 siblings, 0 replies; 33+ messages in thread
From: Sakari Ailus @ 2026-05-18 16:43 UTC (permalink / raw)
  To: linux-media
  Cc: laurent.pinchart, Dave Stevenson, Jacopo Mondi, Tomi Valkeinen,
	Jai Luthra, Mehdi Djait, Frank Li

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 8d28ba0b59a3..7e299ebf3470 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] 33+ messages in thread

* [PATCH v2 10/17] media: nxp: imx8-isi: Use v4l2_subdev_get_frame_desc()
  2026-05-18 16:43 [PATCH v2 00/17] Rework frame descriptors Sakari Ailus
                   ` (8 preceding siblings ...)
  2026-05-18 16:43 ` [PATCH v2 09/17] media: bcm2835-unicam: Use v4l2_subdev_get_frame_desc() Sakari Ailus
@ 2026-05-18 16:43 ` Sakari Ailus
  2026-05-19 22:36   ` Frank Li
  2026-05-18 16:43 ` [PATCH v2 11/17] media: raspberrypi: cfe: " Sakari Ailus
                   ` (8 subsequent siblings)
  18 siblings, 1 reply; 33+ messages in thread
From: Sakari Ailus @ 2026-05-18 16:43 UTC (permalink / raw)
  To: linux-media
  Cc: laurent.pinchart, Dave Stevenson, Jacopo Mondi, Tomi Valkeinen,
	Jai Luthra, Mehdi Djait, Frank Li

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/nxp/imx8-isi/imx8-isi-crossbar.c | 19 ++++++++++---------
 1 file changed, 10 insertions(+), 9 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 605a45124103..545b2addc9ea 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: %ld\n",
+			remote_sd->name, remote_pad, PTR_ERR(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;
 }
 
-- 
2.47.3


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

* [PATCH v2 11/17] media: raspberrypi: cfe: Use v4l2_subdev_get_frame_desc()
  2026-05-18 16:43 [PATCH v2 00/17] Rework frame descriptors Sakari Ailus
                   ` (9 preceding siblings ...)
  2026-05-18 16:43 ` [PATCH v2 10/17] media: nxp: imx8-isi: " Sakari Ailus
@ 2026-05-18 16:43 ` Sakari Ailus
  2026-05-18 16:43 ` [PATCH v2 12/17] media: rzg2l-cru: " Sakari Ailus
                   ` (7 subsequent siblings)
  18 siblings, 0 replies; 33+ messages in thread
From: Sakari Ailus @ 2026-05-18 16:43 UTC (permalink / raw)
  To: linux-media
  Cc: laurent.pinchart, Dave Stevenson, Jacopo Mondi, Tomi Valkeinen,
	Jai Luthra, Mehdi Djait, Frank Li

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/raspberrypi/rp1-cfe/cfe.c  | 28 ++++++++-----------
 1 file changed, 12 insertions(+), 16 deletions(-)

diff --git a/drivers/media/platform/raspberrypi/rp1-cfe/cfe.c b/drivers/media/platform/raspberrypi/rp1-cfe/cfe.c
index 8375ed3e97b9..662a99cee30d 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>
@@ -803,7 +804,6 @@ static int cfe_get_vc_dt_fallback(struct cfe_device *cfe, u8 *vc, u8 *dt)
 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 +816,30 @@ 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) {
+	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 (PTR_ERR(fd) == -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) {
+	} else 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] 33+ messages in thread

* [PATCH v2 12/17] media: rzg2l-cru: Use v4l2_subdev_get_frame_desc()
  2026-05-18 16:43 [PATCH v2 00/17] Rework frame descriptors Sakari Ailus
                   ` (10 preceding siblings ...)
  2026-05-18 16:43 ` [PATCH v2 11/17] media: raspberrypi: cfe: " Sakari Ailus
@ 2026-05-18 16:43 ` Sakari Ailus
  2026-05-18 16:43 ` [PATCH v2 13/17] media: rkisp1: " Sakari Ailus
                   ` (6 subsequent siblings)
  18 siblings, 0 replies; 33+ messages in thread
From: Sakari Ailus @ 2026-05-18 16:43 UTC (permalink / raw)
  To: linux-media
  Cc: laurent.pinchart, Dave Stevenson, Jacopo Mondi, Tomi Valkeinen,
	Jai Luthra, Mehdi Djait, Frank Li

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 162e2ace6931..710fe028fb46 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>
@@ -406,31 +407,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] 33+ messages in thread

* [PATCH v2 13/17] media: rkisp1: Use v4l2_subdev_get_frame_desc()
  2026-05-18 16:43 [PATCH v2 00/17] Rework frame descriptors Sakari Ailus
                   ` (11 preceding siblings ...)
  2026-05-18 16:43 ` [PATCH v2 12/17] media: rzg2l-cru: " Sakari Ailus
@ 2026-05-18 16:43 ` Sakari Ailus
  2026-05-18 16:43 ` [PATCH v2 14/17] media: exynos4-is: " Sakari Ailus
                   ` (5 subsequent siblings)
  18 siblings, 0 replies; 33+ messages in thread
From: Sakari Ailus @ 2026-05-18 16:43 UTC (permalink / raw)
  To: linux-media
  Cc: laurent.pinchart, Dave Stevenson, Jacopo Mondi, Tomi Valkeinen,
	Jai Luthra, Mehdi Djait, Frank Li

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..21d9f7f41411 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: %ld\n",
+			source_sd->name, 0, PTR_ERR(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] 33+ messages in thread

* [PATCH v2 14/17] media: exynos4-is: Use v4l2_subdev_get_frame_desc()
  2026-05-18 16:43 [PATCH v2 00/17] Rework frame descriptors Sakari Ailus
                   ` (12 preceding siblings ...)
  2026-05-18 16:43 ` [PATCH v2 13/17] media: rkisp1: " Sakari Ailus
@ 2026-05-18 16:43 ` Sakari Ailus
  2026-05-18 16:43 ` [PATCH v2 15/17] media: ti: cal: " Sakari Ailus
                   ` (4 subsequent siblings)
  18 siblings, 0 replies; 33+ messages in thread
From: Sakari Ailus @ 2026-05-18 16:43 UTC (permalink / raw)
  To: linux-media
  Cc: laurent.pinchart, Dave Stevenson, Jacopo Mondi, Tomi Valkeinen,
	Jai Luthra, Mehdi Djait, Frank Li

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] 33+ messages in thread

* [PATCH v2 15/17] media: ti: cal: Use v4l2_subdev_get_frame_desc()
  2026-05-18 16:43 [PATCH v2 00/17] Rework frame descriptors Sakari Ailus
                   ` (13 preceding siblings ...)
  2026-05-18 16:43 ` [PATCH v2 14/17] media: exynos4-is: " Sakari Ailus
@ 2026-05-18 16:43 ` Sakari Ailus
  2026-05-18 16:43 ` [PATCH v2 16/17] media: ipu6: " Sakari Ailus
                   ` (3 subsequent siblings)
  18 siblings, 0 replies; 33+ messages in thread
From: Sakari Ailus @ 2026-05-18 16:43 UTC (permalink / raw)
  To: linux-media
  Cc: laurent.pinchart, Dave Stevenson, Jacopo Mondi, Tomi Valkeinen,
	Jai Luthra, Mehdi Djait, Frank Li

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 +++++++++-----------
 1 file changed, 12 insertions(+), 14 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);
-- 
2.47.3


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

* [PATCH v2 16/17] media: ipu6: Use v4l2_subdev_get_frame_desc()
  2026-05-18 16:43 [PATCH v2 00/17] Rework frame descriptors Sakari Ailus
                   ` (14 preceding siblings ...)
  2026-05-18 16:43 ` [PATCH v2 15/17] media: ti: cal: " Sakari Ailus
@ 2026-05-18 16:43 ` Sakari Ailus
  2026-05-18 16:43 ` [PATCH v2 17/17] staging: media: ipu7: " Sakari Ailus
                   ` (2 subsequent siblings)
  18 siblings, 0 replies; 33+ messages in thread
From: Sakari Ailus @ 2026-05-18 16:43 UTC (permalink / raw)
  To: linux-media
  Cc: laurent.pinchart, Dave Stevenson, Jacopo Mondi, Tomi Valkeinen,
	Jai Luthra, Mehdi Djait, Frank Li

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] 33+ messages in thread

* [PATCH v2 17/17] staging: media: ipu7: Use v4l2_subdev_get_frame_desc()
  2026-05-18 16:43 [PATCH v2 00/17] Rework frame descriptors Sakari Ailus
                   ` (15 preceding siblings ...)
  2026-05-18 16:43 ` [PATCH v2 16/17] media: ipu6: " Sakari Ailus
@ 2026-05-18 16:43 ` Sakari Ailus
  2026-06-11 12:49 ` [PATCH v2 00/17] Rework frame descriptors Tomi Valkeinen
  2026-08-14  8:17 ` Mattijs Korpershoek
  18 siblings, 0 replies; 33+ messages in thread
From: Sakari Ailus @ 2026-05-18 16:43 UTC (permalink / raw)
  To: linux-media
  Cc: laurent.pinchart, Dave Stevenson, Jacopo Mondi, Tomi Valkeinen,
	Jai Luthra, Mehdi Djait, Frank Li

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] 33+ messages in thread

* Re: [PATCH v2 04/17] media: v4l2-subdev: Allow releasing frame descriptors on return
  2026-05-18 16:43 ` [PATCH v2 04/17] media: v4l2-subdev: Allow releasing frame descriptors on return Sakari Ailus
@ 2026-05-19 21:34   ` Frank Li
  2026-05-20 12:56     ` Sakari Ailus
  0 siblings, 1 reply; 33+ messages in thread
From: Frank Li @ 2026-05-19 21:34 UTC (permalink / raw)
  To: Sakari Ailus
  Cc: linux-media, laurent.pinchart, Dave Stevenson, Jacopo Mondi,
	Tomi Valkeinen, Jai Luthra, Mehdi Djait

On Mon, May 18, 2026 at 07:43:04PM +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>
> ---
>  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);
> + *

Generally, _get*()/_put*() is well known resource manage pair function
           _alloc()/_free() is pair.
           _request/_free()

Is it a little better v4l2_subdev_request_frame_desc() since get()/put() means
have ref number?

Frank


>   * 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] 33+ messages in thread

* Re: [PATCH v2 05/17] media: v4l2-subdev: Allocate frame descriptors based on the need
  2026-05-18 16:43 ` [PATCH v2 05/17] media: v4l2-subdev: Allocate frame descriptors based on the need Sakari Ailus
@ 2026-05-19 21:53   ` Frank Li
  2026-05-19 22:18     ` Frank Li
  0 siblings, 1 reply; 33+ messages in thread
From: Frank Li @ 2026-05-19 21:53 UTC (permalink / raw)
  To: Sakari Ailus
  Cc: linux-media, laurent.pinchart, Dave Stevenson, Jacopo Mondi,
	Tomi Valkeinen, Jai Luthra, Mehdi Djait

On Mon, May 18, 2026 at 07:43:05PM +0300, Sakari Ailus wrote:
> 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 allocating as much memory as required.
> The get_frame_desc() op can now set the num_entries to a number larger
> than V4L2_FRAME_BUS_ENTRY_PREALLOC and return -ENOSPC. The caller,
> v4l2_subdev_get_frame_desc(), will then allocate memory for that amount of
> memory and call the get_frame_desc() op again.
>
> 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>
> ---
...
>  /**
>   * 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;

name is not direct reflect means and quite easy to confuse with num_entries.
Is it num_dym_entries or other names little better?

Frank
>  };
>
>  /**
> @@ -781,7 +787,14 @@ 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 num_entries exceeds len_entries, the callback
> + *		    shall return -ENOSPC. Never call this directly in drivers,
> + *		    use v4l2_subdev_get_frame_desc() instead.
>   *
>   * @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 +1807,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 +1827,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	[flat|nested] 33+ messages in thread

* Re: [PATCH v2 06/17] media: v4l2-subdev: Change the maximum number of routes
  2026-05-18 16:43 ` [PATCH v2 06/17] media: v4l2-subdev: Change the maximum number of routes Sakari Ailus
@ 2026-05-19 21:55   ` Frank Li
  0 siblings, 0 replies; 33+ messages in thread
From: Frank Li @ 2026-05-19 21:55 UTC (permalink / raw)
  To: Sakari Ailus
  Cc: linux-media, laurent.pinchart, Dave Stevenson, Jacopo Mondi,
	Tomi Valkeinen, Jai Luthra, Mehdi Djait

On Mon, May 18, 2026 at 07:43:06PM +0300, Sakari Ailus wrote:
> 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 da8464dfb265..ebcc0b40fac1 100644
> --- a/drivers/media/v4l2-core/v4l2-subdev.c
> +++ b/drivers/media/v4l2-core/v4l2-subdev.c
> @@ -1103,14 +1103,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	[flat|nested] 33+ messages in thread

* Re: [PATCH v2 05/17] media: v4l2-subdev: Allocate frame descriptors based on the need
  2026-05-19 21:53   ` Frank Li
@ 2026-05-19 22:18     ` Frank Li
  0 siblings, 0 replies; 33+ messages in thread
From: Frank Li @ 2026-05-19 22:18 UTC (permalink / raw)
  To: Sakari Ailus
  Cc: linux-media, laurent.pinchart, Dave Stevenson, Jacopo Mondi,
	Tomi Valkeinen, Jai Luthra, Mehdi Djait

On Tue, May 19, 2026 at 05:53:57PM -0400, Frank Li wrote:
> On Mon, May 18, 2026 at 07:43:05PM +0300, Sakari Ailus wrote:
> > 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 allocating as much memory as required.
> > The get_frame_desc() op can now set the num_entries to a number larger
> > than V4L2_FRAME_BUS_ENTRY_PREALLOC and return -ENOSPC. The caller,
> > v4l2_subdev_get_frame_desc(), will then allocate memory for that amount of
> > memory and call the get_frame_desc() op again.
> >
> > 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>
> > ---
> ...
> >  /**
> >   * 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;
>
> name is not direct reflect means and quite easy to confuse with num_entries.
> Is it num_dym_entries or other names little better?

Please ignore this comments. I understand what's means.

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

Frank
>
> Frank
> >  };
> >
> >  /**
> > @@ -781,7 +787,14 @@ 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 num_entries exceeds len_entries, the callback
> > + *		    shall return -ENOSPC. Never call this directly in drivers,
> > + *		    use v4l2_subdev_get_frame_desc() instead.
> >   *
> >   * @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 +1807,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 +1827,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	[flat|nested] 33+ messages in thread

* Re: [PATCH v2 07/17] media: v4l2-subdev: Return dynamically allocated pass-through routes
  2026-05-18 16:43 ` [PATCH v2 07/17] media: v4l2-subdev: Return dynamically allocated pass-through routes Sakari Ailus
@ 2026-05-19 22:33   ` Frank Li
  2026-05-20 12:59     ` Sakari Ailus
  0 siblings, 1 reply; 33+ messages in thread
From: Frank Li @ 2026-05-19 22:33 UTC (permalink / raw)
  To: Sakari Ailus
  Cc: linux-media, laurent.pinchart, Dave Stevenson, Jacopo Mondi,
	Tomi Valkeinen, Jai Luthra, Mehdi Djait

On Mon, May 18, 2026 at 07:43:07PM +0300, Sakari Ailus wrote:
> Count the number of pass-through routes and then return the full table
> once enough memory is available for it.
>
> Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
> ---
>  drivers/media/v4l2-core/v4l2-subdev.c | 12 +++++++-----
>  1 file changed, 7 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/media/v4l2-core/v4l2-subdev.c b/drivers/media/v4l2-core/v4l2-subdev.c
> index ebcc0b40fac1..b5eef0baa237 100644
> --- a/drivers/media/v4l2-core/v4l2-subdev.c
> +++ b/drivers/media/v4l2-core/v4l2-subdev.c
> @@ -2653,20 +2653,22 @@ int __v4l2_subdev_get_frame_desc_passthrough(struct v4l2_subdev *sd,
>  				return -EPIPE;
>  			}
>
> -			if (fd->num_entries >= V4L2_FRAME_DESC_ENTRY_PREALLOC) {
> +			if (fd->num_entries >= V4L2_FRAME_DESC_ENTRY_MAX) {
>  				dev_dbg(dev, "Frame desc entry limit reached\n");
>  				return -E2BIG;
>  			}
>
> -			fd->entry[fd->num_entries] = *source_entry;
> -
> -			fd->entry[fd->num_entries].stream = route->source_stream;
> +			if (fd->num_entries < fd->len_entries) {

Peasonally, I prefer use an explicit method to get total entries number
instead of mix these.

we can use the get_frame_desc(), but use fd->entry == NULL means get
total entries number.

bad thing is that always call twice compared to current method.

Frank

> +				fd->entry[fd->num_entries] = *source_entry;
> +				fd->entry[fd->num_entries].stream =
> +					route->source_stream;
> +			}
>
>  			fd->num_entries++;
>  		}
>  	}
>
> -	return 0;
> +	return fd->num_entries < fd->len_entries ? 0 : -ENOSPC;
>  }
>  EXPORT_SYMBOL_GPL(__v4l2_subdev_get_frame_desc_passthrough);
>
> --
> 2.47.3
>

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

* Re: [PATCH v2 08/17] media: v4l2-subdev: Always return at least one frame descriptor
  2026-05-18 16:43 ` [PATCH v2 08/17] media: v4l2-subdev: Always return at least one frame descriptor Sakari Ailus
@ 2026-05-19 22:35   ` Frank Li
  0 siblings, 0 replies; 33+ messages in thread
From: Frank Li @ 2026-05-19 22:35 UTC (permalink / raw)
  To: Sakari Ailus
  Cc: linux-media, laurent.pinchart, Dave Stevenson, Jacopo Mondi,
	Tomi Valkeinen, Jai Luthra, Mehdi Djait

On Mon, May 18, 2026 at 07:43:08PM +0300, Sakari Ailus wrote:
> 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 b5eef0baa237..dc4ac08c210f 100644
> --- a/drivers/media/v4l2-core/v4l2-subdev.c
> +++ b/drivers/media/v4l2-core/v4l2-subdev.c
> @@ -2732,6 +2732,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 f9b121eefa92..0361c8bbee38 100644
> --- a/include/media/v4l2-subdev.h
> +++ b/include/media/v4l2-subdev.h
> @@ -1817,6 +1817,8 @@ int v4l2_subdev_get_frame_desc_passthrough(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	[flat|nested] 33+ messages in thread

* Re: [PATCH v2 10/17] media: nxp: imx8-isi: Use v4l2_subdev_get_frame_desc()
  2026-05-18 16:43 ` [PATCH v2 10/17] media: nxp: imx8-isi: " Sakari Ailus
@ 2026-05-19 22:36   ` Frank Li
  0 siblings, 0 replies; 33+ messages in thread
From: Frank Li @ 2026-05-19 22:36 UTC (permalink / raw)
  To: Sakari Ailus
  Cc: linux-media, laurent.pinchart, Dave Stevenson, Jacopo Mondi,
	Tomi Valkeinen, Jai Luthra, Mehdi Djait

On Mon, May 18, 2026 at 07:43:10PM +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/nxp/imx8-isi/imx8-isi-crossbar.c | 19 ++++++++++---------
>  1 file changed, 10 insertions(+), 9 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 605a45124103..545b2addc9ea 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: %ld\n",
> +			remote_sd->name, remote_pad, PTR_ERR(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;
>  }
>
> --
> 2.47.3
>

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

* Re: [PATCH v2 04/17] media: v4l2-subdev: Allow releasing frame descriptors on return
  2026-05-19 21:34   ` Frank Li
@ 2026-05-20 12:56     ` Sakari Ailus
  0 siblings, 0 replies; 33+ messages in thread
From: Sakari Ailus @ 2026-05-20 12:56 UTC (permalink / raw)
  To: Frank Li
  Cc: linux-media, laurent.pinchart, Dave Stevenson, Jacopo Mondi,
	Tomi Valkeinen, Jai Luthra, Mehdi Djait

Hi Frank,

Thanks for the review.

On Tue, May 19, 2026 at 05:34:37PM -0400, Frank Li wrote:
> On Mon, May 18, 2026 at 07:43:04PM +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>
> > ---
> >  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);
> > + *
> 
> Generally, _get*()/_put*() is well known resource manage pair function
>            _alloc()/_free() is pair.
>            _request/_free()
> 
> Is it a little better v4l2_subdev_request_frame_desc() since get()/put() means
> have ref number?

We have similar v4l2_subdev_get_* calls that obtain various things like the
mbus format or selections, and that naming isn't aligned with get/put
either. I'm not entirely happy with the existing naming but changing it
would be a major amount of work for little gain. Either way, it still
aligns well with v4l2_subdev_get_frame_desc().

In fact I called the function v4l2_subdev_alloc_frame_desc() earlier but
changed the name as its main function is to obtain the frame descriptor by
using various means, not so much the allocation.

There will about ten users of the function albeit it'll grow slowly over
time.

-- 
Kind regards,

Sakari Ailus

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

* Re: [PATCH v2 07/17] media: v4l2-subdev: Return dynamically allocated pass-through routes
  2026-05-19 22:33   ` Frank Li
@ 2026-05-20 12:59     ` Sakari Ailus
  0 siblings, 0 replies; 33+ messages in thread
From: Sakari Ailus @ 2026-05-20 12:59 UTC (permalink / raw)
  To: Frank Li
  Cc: linux-media, laurent.pinchart, Dave Stevenson, Jacopo Mondi,
	Tomi Valkeinen, Jai Luthra, Mehdi Djait

Hi Frank,

On Tue, May 19, 2026 at 06:33:01PM -0400, Frank Li wrote:
> On Mon, May 18, 2026 at 07:43:07PM +0300, Sakari Ailus wrote:
> > Count the number of pass-through routes and then return the full table
> > once enough memory is available for it.
> >
> > Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
> > ---
> >  drivers/media/v4l2-core/v4l2-subdev.c | 12 +++++++-----
> >  1 file changed, 7 insertions(+), 5 deletions(-)
> >
> > diff --git a/drivers/media/v4l2-core/v4l2-subdev.c b/drivers/media/v4l2-core/v4l2-subdev.c
> > index ebcc0b40fac1..b5eef0baa237 100644
> > --- a/drivers/media/v4l2-core/v4l2-subdev.c
> > +++ b/drivers/media/v4l2-core/v4l2-subdev.c
> > @@ -2653,20 +2653,22 @@ int __v4l2_subdev_get_frame_desc_passthrough(struct v4l2_subdev *sd,
> >  				return -EPIPE;
> >  			}
> >
> > -			if (fd->num_entries >= V4L2_FRAME_DESC_ENTRY_PREALLOC) {
> > +			if (fd->num_entries >= V4L2_FRAME_DESC_ENTRY_MAX) {
> >  				dev_dbg(dev, "Frame desc entry limit reached\n");
> >  				return -E2BIG;
> >  			}
> >
> > -			fd->entry[fd->num_entries] = *source_entry;
> > -
> > -			fd->entry[fd->num_entries].stream = route->source_stream;
> > +			if (fd->num_entries < fd->len_entries) {
> 
> Peasonally, I prefer use an explicit method to get total entries number
> instead of mix these.

That might be a little cleaner but seemed overkill to me while implementing
this. I wonder what others think.

> 
> we can use the get_frame_desc(), but use fd->entry == NULL means get
> total entries number.

The existing implementations expect the entry field is valid.

> 
> bad thing is that always call twice compared to current method.

-- 
Regards,

Sakari Ailus

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

* Re: [PATCH v2 00/17] Rework frame descriptors
  2026-05-18 16:43 [PATCH v2 00/17] Rework frame descriptors Sakari Ailus
                   ` (16 preceding siblings ...)
  2026-05-18 16:43 ` [PATCH v2 17/17] staging: media: ipu7: " Sakari Ailus
@ 2026-06-11 12:49 ` Tomi Valkeinen
  2026-06-12  8:28   ` Sakari Ailus
  2026-06-23  7:39   ` Sakari Ailus
  2026-08-14  8:17 ` Mattijs Korpershoek
  18 siblings, 2 replies; 33+ messages in thread
From: Tomi Valkeinen @ 2026-06-11 12:49 UTC (permalink / raw)
  To: Sakari Ailus, linux-media
  Cc: laurent.pinchart, Dave Stevenson, Jacopo Mondi, Jai Luthra,
	Mehdi Djait, Frank Li

Hi Sakari,

On 18/05/2026 19:43, Sakari Ailus wrote:
> Hi folks,
> 
> This smallish set makes frame descriptors dynamically allocated and

Is there a real-life requirement for this? 8 frame-descs per pad has 
been more than enough for my uses so far.

> 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

Hmm, what does this mean? Don't all the drivers modified here already 
get their frame desc from upstream? Or did you mean "all drivers that 
obtain their frame desc from upstream..."?

> 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

What does this mean? In patch 3, the desc says "If the remote sub-device 
does not support frame descriptors, v4l2_subdev_get_frame_desc() creates 
one".

So does v4l2_subdev_get_frame_desc() just check, or does 
v4l2_subdev_get_frame_desc() implement a fallback mechanism, if the 
upstream subdev does not implement .get_frame_desc?

If it does, some of the drivers implement their own fallback. E.g. rpi 
cfe.c calls cfe_get_vc_dt_fallback() if it gets -ENOIOCTLCMD, which just 
constructs a default single-stream frame desc with virtual channel 0.

It also looks like you only modified platform drivers. Did you check the 
i2c drivers? Some call get_frame_desc().

> 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.)

Hmm, isn't that strictly tied to the multi-stream support? Or do you 
mean that frame desc could contain multiple entries, but the receiver 
would only use one (if multi-stream is not supported)?

  Tomi


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

* Re: [PATCH v2 00/17] Rework frame descriptors
  2026-06-11 12:49 ` [PATCH v2 00/17] Rework frame descriptors Tomi Valkeinen
@ 2026-06-12  8:28   ` Sakari Ailus
  2026-06-23  7:39   ` Sakari Ailus
  1 sibling, 0 replies; 33+ messages in thread
From: Sakari Ailus @ 2026-06-12  8:28 UTC (permalink / raw)
  To: Tomi Valkeinen
  Cc: linux-media, laurent.pinchart, Dave Stevenson, Jacopo Mondi,
	Jai Luthra, Mehdi Djait, Frank Li

Moi,

On Thu, Jun 11, 2026 at 03:49:13PM +0300, Tomi Valkeinen wrote:
> Hi Sakari,
> 
> On 18/05/2026 19:43, Sakari Ailus wrote:
> > Hi folks,
> > 
> > This smallish set makes frame descriptors dynamically allocated and
> 
> Is there a real-life requirement for this? 8 frame-descs per pad has been
> more than enough for my uses so far.

Not in upstream right now. But I see this as a general improvement so I'd
be inclined to merge support for it.

The next hard limit is 64 (bits in u64).

> 
> > 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
> 
> Hmm, what does this mean? Don't all the drivers modified here already get
> their frame desc from upstream? Or did you mean "all drivers that obtain
> their frame desc from upstream..."?

I think there's an extra "not" indeed.

> 
> > 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
> 
> What does this mean? In patch 3, the desc says "If the remote sub-device
> does not support frame descriptors, v4l2_subdev_get_frame_desc() creates
> one".
> 
> So does v4l2_subdev_get_frame_desc() just check, or does
> v4l2_subdev_get_frame_desc() implement a fallback mechanism, if the upstream
> subdev does not implement .get_frame_desc?

There's a fallback mechanism, yes. Otherwise it wouldn't be very useful.

> 
> If it does, some of the drivers implement their own fallback. E.g. rpi cfe.c
> calls cfe_get_vc_dt_fallback() if it gets -ENOIOCTLCMD, which just
> constructs a default single-stream frame desc with virtual channel 0.

I'll remove this in the next version.

> 
> It also looks like you only modified platform drivers. Did you check the i2c
> drivers? Some call get_frame_desc().

I could have missed some, I'll check again.

> 
> > 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.)
> 
> Hmm, isn't that strictly tied to the multi-stream support? Or do you mean

Not really. These are existing drivers that do not support multiple
streams.

> that frame desc could contain multiple entries, but the receiver would only
> use one (if multi-stream is not supported)?

Correct. Some currently fail if there are more entries and others just use
the first one.

-- 
Regards,

Sakari Ailus

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

* Re: [PATCH v2 00/17] Rework frame descriptors
  2026-06-11 12:49 ` [PATCH v2 00/17] Rework frame descriptors Tomi Valkeinen
  2026-06-12  8:28   ` Sakari Ailus
@ 2026-06-23  7:39   ` Sakari Ailus
  1 sibling, 0 replies; 33+ messages in thread
From: Sakari Ailus @ 2026-06-23  7:39 UTC (permalink / raw)
  To: Tomi Valkeinen
  Cc: linux-media, laurent.pinchart, Dave Stevenson, Jacopo Mondi,
	Jai Luthra, Mehdi Djait, Frank Li

Moi,

On Thu, Jun 11, 2026 at 03:49:13PM +0300, Tomi Valkeinen wrote:
> Hi Sakari,
> 
> On 18/05/2026 19:43, Sakari Ailus wrote:
> > Hi folks,
> > 
> > This smallish set makes frame descriptors dynamically allocated and
> 
> Is there a real-life requirement for this? 8 frame-descs per pad has been
> more than enough for my uses so far.

Imagine cameras producing four streams each, and putting a number of them
behind CSI-2 aggregators (or some serdes device). It does happen in
practice.

> 
> > 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
> 
> Hmm, what does this mean? Don't all the drivers modified here already get
> their frame desc from upstream? Or did you mean "all drivers that obtain
> their frame desc from upstream..."?

This was meant to say that the drivers that called get_frame_desc()
directly but did not implement .get_frame_desc() pad op are converted while
the rest aren't. I'll rephrase this for v3.

> 
> > 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
> 
> What does this mean? In patch 3, the desc says "If the remote sub-device
> does not support frame descriptors, v4l2_subdev_get_frame_desc() creates
> one".
> 
> So does v4l2_subdev_get_frame_desc() just check, or does
> v4l2_subdev_get_frame_desc() implement a fallback mechanism, if the upstream
> subdev does not implement .get_frame_desc?

Correct.

> 
> If it does, some of the drivers implement their own fallback. E.g. rpi cfe.c
> calls cfe_get_vc_dt_fallback() if it gets -ENOIOCTLCMD, which just
> constructs a default single-stream frame desc with virtual channel 0.

This fallback can be then removed, yes. I'll check the drivers again in v3.

> 
> It also looks like you only modified platform drivers. Did you check the i2c
> drivers? Some call get_frame_desc().

I guess they all use various frame descriptor pass-through functions
nowadays.

> 
> > 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.)
> 
> Hmm, isn't that strictly tied to the multi-stream support? Or do you mean
> that frame desc could contain multiple entries, but the receiver would only
> use one (if multi-stream is not supported)?

It's not strictly tied to multi-stream support. Most receiver drivers can
receive a single stream even if the source generates more than that. The
only one that can't do that which I'm aware of is some Xilinx device; I
recall Laurent knows more about it.

-- 
Terveisin,

Sakari Ailus

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

* Re: [PATCH v2 00/17] Rework frame descriptors
  2026-05-18 16:43 [PATCH v2 00/17] Rework frame descriptors Sakari Ailus
                   ` (17 preceding siblings ...)
  2026-06-11 12:49 ` [PATCH v2 00/17] Rework frame descriptors Tomi Valkeinen
@ 2026-08-14  8:17 ` Mattijs Korpershoek
  2026-08-14  8:21   ` Tomi Valkeinen
  18 siblings, 1 reply; 33+ messages in thread
From: Mattijs Korpershoek @ 2026-08-14  8:17 UTC (permalink / raw)
  To: Sakari Ailus, linux-media
  Cc: laurent.pinchart, Dave Stevenson, Jacopo Mondi, Tomi Valkeinen,
	Jai Luthra, Mehdi Djait, Frank Li

Hi Sakari,

Thank you for the series.

On Mon, May 18, 2026 at 19:43, 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.)
>
> On callee side these patches introduce no changes as the number of
> pre-allocated memory for 8 frame descriptors remains as-is. The
> get_frame_desc() pad op can return more than 8 frame descriptors by
> setting the num_entries to the desired number and returning -ENOSPC.
>
> If people prefer using cleanup.h / __free() to release the dynamically
> allocated array (I think I'd almost require that), I'll merge the
> now-separate __v4l2_subdev_get_frame_desc() into
> v4l2_subdev_get_frame_desc().
>
> 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).

I've tried this out on a 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 documentation about this [2]

I (naively) assumed that this series would replace Tomi's patch [3], but
it did not. I see the following in dmesg:

[  286.686574] cdns-csi2rx 4504000.csi-bridge: collect_streams: "cdns_csi2rx.4504000.csi-bridge":1: found 0x1 enabled 0x0
[  286.686754] ds90ub953 7-0044: Failed to get frame desc from remote subdev imx219 10-0010
[  286.700147] ds90ub960 7-0030: Failed to get source frame desc for pad 0
[  286.712679] j721e-csi2rx 4500000.ticsi2rx: enable streams "ds90ub960 7-0030":4/0x1
[  286.712684] ds90ub960 7-0030: collect_streams: "ds90ub960 7-0030":4: found 0x1 enabled 0x0
[  286.712690] ds90ub953 7-0044: Failed to get frame desc from remote subdev imx219 10-0010
[  286.725884] j721e-csi2rx 4500000.ticsi2rx: enable streams 4:0x1 failed: -515

Here is my camera topology:
https://paste.debian.net/hidden/7f56f635

I also made the following patch to attempt to convert over j721e-csi2rx:
https://paste.debian.net/hidden/314f9c32

Is this series indeed aimed to replace all sensor-specific
implementations of .get_frame_desc() or are patches such as the one send
from Tomi [3] still useful?

Thanks
Mattijs

[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
[3] https://lore.kernel.org/all/20260611-imx219-frame-desc-v1-1-fe7e975bca6e@ideasonboard.com/

>
> since v1:
>

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

* Re: [PATCH v2 00/17] Rework frame descriptors
  2026-08-14  8:17 ` Mattijs Korpershoek
@ 2026-08-14  8:21   ` Tomi Valkeinen
  2026-08-14  9:26     ` Mattijs Korpershoek
  0 siblings, 1 reply; 33+ messages in thread
From: Tomi Valkeinen @ 2026-08-14  8:21 UTC (permalink / raw)
  To: Mattijs Korpershoek, Sakari Ailus, linux-media
  Cc: laurent.pinchart, Dave Stevenson, Jacopo Mondi, Jai Luthra,
	Mehdi Djait, Frank Li

Hi,

On 14/08/2026 11:17, Mattijs Korpershoek wrote:
> Hi Sakari,
> 
> Thank you for the series.
> 
> On Mon, May 18, 2026 at 19:43, 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.)
>>
>> On callee side these patches introduce no changes as the number of
>> pre-allocated memory for 8 frame descriptors remains as-is. The
>> get_frame_desc() pad op can return more than 8 frame descriptors by
>> setting the num_entries to the desired number and returning -ENOSPC.
>>
>> If people prefer using cleanup.h / __free() to release the dynamically
>> allocated array (I think I'd almost require that), I'll merge the
>> now-separate __v4l2_subdev_get_frame_desc() into
>> v4l2_subdev_get_frame_desc().
>>
>> 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).
> 
> I've tried this out on a 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 documentation about this [2]
> 
> I (naively) assumed that this series would replace Tomi's patch [3], but
> it did not. I see the following in dmesg:
> 
> [  286.686574] cdns-csi2rx 4504000.csi-bridge: collect_streams: "cdns_csi2rx.4504000.csi-bridge":1: found 0x1 enabled 0x0
> [  286.686754] ds90ub953 7-0044: Failed to get frame desc from remote subdev imx219 10-0010
> [  286.700147] ds90ub960 7-0030: Failed to get source frame desc for pad 0
> [  286.712679] j721e-csi2rx 4500000.ticsi2rx: enable streams "ds90ub960 7-0030":4/0x1
> [  286.712684] ds90ub960 7-0030: collect_streams: "ds90ub960 7-0030":4: found 0x1 enabled 0x0
> [  286.712690] ds90ub953 7-0044: Failed to get frame desc from remote subdev imx219 10-0010
> [  286.725884] j721e-csi2rx 4500000.ticsi2rx: enable streams 4:0x1 failed: -515
> 
> Here is my camera topology:
> https://paste.debian.net/hidden/7f56f635
> 
> I also made the following patch to attempt to convert over j721e-csi2rx:
> https://paste.debian.net/hidden/314f9c32
> 
> Is this series indeed aimed to replace all sensor-specific
> implementations of .get_frame_desc() or are patches such as the one send
> from Tomi [3] still useful?
I don't remember the details anymore, but probably related to my comment 
in this thread:

"It also looks like you only modified platform drivers. Did you check 
the i2c drivers? Some call get_frame_desc().". So I think ub953 is 
missing the conversion to v4l2_subdev_get_frame_desc().

  Tomi


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

* Re: [PATCH v2 00/17] Rework frame descriptors
  2026-08-14  8:21   ` Tomi Valkeinen
@ 2026-08-14  9:26     ` Mattijs Korpershoek
  0 siblings, 0 replies; 33+ messages in thread
From: Mattijs Korpershoek @ 2026-08-14  9:26 UTC (permalink / raw)
  To: Tomi Valkeinen, Mattijs Korpershoek, Sakari Ailus, linux-media
  Cc: laurent.pinchart, Dave Stevenson, Jacopo Mondi, Jai Luthra,
	Mehdi Djait, Frank Li

Hi Tomi,

On Fri, Aug 14, 2026 at 11:21, Tomi Valkeinen <tomi.valkeinen@ideasonboard.com> wrote:

> Hi,
>
> On 14/08/2026 11:17, Mattijs Korpershoek wrote:
>> Hi Sakari,
>> 
>> Thank you for the series.
>> 
>> On Mon, May 18, 2026 at 19:43, 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.)
>>>
>>> On callee side these patches introduce no changes as the number of
>>> pre-allocated memory for 8 frame descriptors remains as-is. The
>>> get_frame_desc() pad op can return more than 8 frame descriptors by
>>> setting the num_entries to the desired number and returning -ENOSPC.
>>>
>>> If people prefer using cleanup.h / __free() to release the dynamically
>>> allocated array (I think I'd almost require that), I'll merge the
>>> now-separate __v4l2_subdev_get_frame_desc() into
>>> v4l2_subdev_get_frame_desc().
>>>
>>> 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).
>> 
>> I've tried this out on a 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 documentation about this [2]
>> 
>> I (naively) assumed that this series would replace Tomi's patch [3], but
>> it did not. I see the following in dmesg:
>> 
>> [  286.686574] cdns-csi2rx 4504000.csi-bridge: collect_streams: "cdns_csi2rx.4504000.csi-bridge":1: found 0x1 enabled 0x0
>> [  286.686754] ds90ub953 7-0044: Failed to get frame desc from remote subdev imx219 10-0010
>> [  286.700147] ds90ub960 7-0030: Failed to get source frame desc for pad 0
>> [  286.712679] j721e-csi2rx 4500000.ticsi2rx: enable streams "ds90ub960 7-0030":4/0x1
>> [  286.712684] ds90ub960 7-0030: collect_streams: "ds90ub960 7-0030":4: found 0x1 enabled 0x0
>> [  286.712690] ds90ub953 7-0044: Failed to get frame desc from remote subdev imx219 10-0010
>> [  286.725884] j721e-csi2rx 4500000.ticsi2rx: enable streams 4:0x1 failed: -515
>> 
>> Here is my camera topology:
>> https://paste.debian.net/hidden/7f56f635
>> 
>> I also made the following patch to attempt to convert over j721e-csi2rx:
>> https://paste.debian.net/hidden/314f9c32
>> 
>> Is this series indeed aimed to replace all sensor-specific
>> implementations of .get_frame_desc() or are patches such as the one send
>> from Tomi [3] still useful?
> I don't remember the details anymore, but probably related to my comment 
> in this thread:
>
> "It also looks like you only modified platform drivers. Did you check 
> the i2c drivers? Some call get_frame_desc().". So I think ub953 is 
> missing the conversion to v4l2_subdev_get_frame_desc().

Thanks for the hint.

ub953 and ub960 (which I both use) indirectly call .get_frame_desc() via
v4l2_subdev_get_frame_desc_passthrough().

So maybe v4l2_subdev_get_frame_desc_passthrough() needs an update as
well in this series.

>
>   Tomi

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

end of thread, other threads:[~2026-08-14  9:26 UTC | newest]

Thread overview: 33+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-05-18 16:43 [PATCH v2 00/17] Rework frame descriptors Sakari Ailus
2026-05-18 16:43 ` [PATCH v2 01/17] media: v4l2-common: Add helper function media_bus_fmt_to_csi2_(bpp|dt)() Sakari Ailus
2026-05-18 16:43 ` [PATCH v2 02/17] media: v4l2-subdev: Align frame descriptor error codes with routing Sakari Ailus
2026-05-18 16:43 ` [PATCH v2 03/17] media: v4l2-subdev: Prepare for changes in getting frame descriptors Sakari Ailus
2026-05-18 16:43 ` [PATCH v2 04/17] media: v4l2-subdev: Allow releasing frame descriptors on return Sakari Ailus
2026-05-19 21:34   ` Frank Li
2026-05-20 12:56     ` Sakari Ailus
2026-05-18 16:43 ` [PATCH v2 05/17] media: v4l2-subdev: Allocate frame descriptors based on the need Sakari Ailus
2026-05-19 21:53   ` Frank Li
2026-05-19 22:18     ` Frank Li
2026-05-18 16:43 ` [PATCH v2 06/17] media: v4l2-subdev: Change the maximum number of routes Sakari Ailus
2026-05-19 21:55   ` Frank Li
2026-05-18 16:43 ` [PATCH v2 07/17] media: v4l2-subdev: Return dynamically allocated pass-through routes Sakari Ailus
2026-05-19 22:33   ` Frank Li
2026-05-20 12:59     ` Sakari Ailus
2026-05-18 16:43 ` [PATCH v2 08/17] media: v4l2-subdev: Always return at least one frame descriptor Sakari Ailus
2026-05-19 22:35   ` Frank Li
2026-05-18 16:43 ` [PATCH v2 09/17] media: bcm2835-unicam: Use v4l2_subdev_get_frame_desc() Sakari Ailus
2026-05-18 16:43 ` [PATCH v2 10/17] media: nxp: imx8-isi: " Sakari Ailus
2026-05-19 22:36   ` Frank Li
2026-05-18 16:43 ` [PATCH v2 11/17] media: raspberrypi: cfe: " Sakari Ailus
2026-05-18 16:43 ` [PATCH v2 12/17] media: rzg2l-cru: " Sakari Ailus
2026-05-18 16:43 ` [PATCH v2 13/17] media: rkisp1: " Sakari Ailus
2026-05-18 16:43 ` [PATCH v2 14/17] media: exynos4-is: " Sakari Ailus
2026-05-18 16:43 ` [PATCH v2 15/17] media: ti: cal: " Sakari Ailus
2026-05-18 16:43 ` [PATCH v2 16/17] media: ipu6: " Sakari Ailus
2026-05-18 16:43 ` [PATCH v2 17/17] staging: media: ipu7: " Sakari Ailus
2026-06-11 12:49 ` [PATCH v2 00/17] Rework frame descriptors Tomi Valkeinen
2026-06-12  8:28   ` Sakari Ailus
2026-06-23  7:39   ` Sakari Ailus
2026-08-14  8:17 ` Mattijs Korpershoek
2026-08-14  8:21   ` Tomi Valkeinen
2026-08-14  9:26     ` Mattijs Korpershoek

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