Linux-ARM-Kernel Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 02/16] media: sun6i-csi: capture: Implement vidioc_enum_framesizes
From: Paul Kocialkowski @ 2026-05-18 10:24 UTC (permalink / raw)
  To: linux-media, linux-arm-kernel, linux-sunxi, linux-kernel,
	linux-staging
  Cc: Paul Kocialkowski, Mauro Carvalho Chehab, Chen-Yu Tsai,
	Jernej Skrabec, Samuel Holland, Greg Kroah-Hartman, Arash Golgol,
	Laurent Pinchart, Nicolas Dufresne
In-Reply-To: <20260518102451.417971-1-paulk@sys-base.io>

From: Arash Golgol <arash.golgol@gmail.com>

Report the stepwise frame size range supported by the CSI capture
hardware for the pixel formats exposed by the driver.

The hardware does not perform scaling and accepts any even width and
height within the reported limits.

Signed-off-by: Arash Golgol <arash.golgol@gmail.com>
Reviewed-by: Paul Kocialkowski <paulk@sys-base.io>
Tested-by: Paul Kocialkowski <paulk@sys-base.io>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
---
 .../sunxi/sun6i-csi/sun6i_csi_capture.c       | 22 +++++++++++++++++++
 1 file changed, 22 insertions(+)

diff --git a/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi_capture.c b/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi_capture.c
index d90abba21309..f788b4234673 100644
--- a/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi_capture.c
+++ b/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi_capture.c
@@ -738,6 +738,27 @@ static int sun6i_csi_capture_enum_fmt(struct file *file, void *priv,
 	return 0;
 }
 
+static int sun6i_csi_capture_enum_framesize(struct file *file, void *fh,
+					    struct v4l2_frmsizeenum *fsize)
+{
+	if (fsize->index)
+		return -EINVAL;
+
+	/* Only accept format in map table. */
+	if (!sun6i_csi_capture_format_find(fsize->pixel_format))
+		return -EINVAL;
+
+	fsize->type = V4L2_FRMSIZE_TYPE_STEPWISE;
+	fsize->stepwise.min_width = SUN6I_CSI_CAPTURE_WIDTH_MIN;
+	fsize->stepwise.max_width = SUN6I_CSI_CAPTURE_WIDTH_MAX;
+	fsize->stepwise.min_height = SUN6I_CSI_CAPTURE_HEIGHT_MIN;
+	fsize->stepwise.max_height = SUN6I_CSI_CAPTURE_HEIGHT_MAX;
+	fsize->stepwise.step_width = 2;
+	fsize->stepwise.step_height = 2;
+
+	return 0;
+}
+
 static int sun6i_csi_capture_g_fmt(struct file *file, void *priv,
 				   struct v4l2_format *format)
 {
@@ -805,6 +826,7 @@ static const struct v4l2_ioctl_ops sun6i_csi_capture_ioctl_ops = {
 	.vidioc_querycap		= sun6i_csi_capture_querycap,
 
 	.vidioc_enum_fmt_vid_cap	= sun6i_csi_capture_enum_fmt,
+	.vidioc_enum_framesizes		= sun6i_csi_capture_enum_framesize,
 	.vidioc_g_fmt_vid_cap		= sun6i_csi_capture_g_fmt,
 	.vidioc_s_fmt_vid_cap		= sun6i_csi_capture_s_fmt,
 	.vidioc_try_fmt_vid_cap		= sun6i_csi_capture_try_fmt,
-- 
2.54.0



^ permalink raw reply related

* [PATCH 03/16] media: sun6i-mipi-csi2: Use V4L2 subdev active state
From: Paul Kocialkowski @ 2026-05-18 10:24 UTC (permalink / raw)
  To: linux-media, linux-arm-kernel, linux-sunxi, linux-kernel,
	linux-staging
  Cc: Paul Kocialkowski, Mauro Carvalho Chehab, Chen-Yu Tsai,
	Jernej Skrabec, Samuel Holland, Greg Kroah-Hartman, Arash Golgol,
	Laurent Pinchart, Nicolas Dufresne
In-Reply-To: <20260518102451.417971-1-paulk@sys-base.io>

From: Arash Golgol <arash.golgol@gmail.com>

Use the V4L2 subdev active state API to store the active format.
This simplifies the driver not only by dropping the bridge mbus_format
field, but it also allows dropping the bridge lock, replaced with
the state lock.

The sun6i-mipi-csi2 hardware does not perform any format conversion.
Enforce identical formats on the sink and source pads in the set_fmt()
and init_state() callbacks.

Signed-off-by: Arash Golgol <arash.golgol@gmail.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
---
 .../sunxi/sun6i-mipi-csi2/sun6i_mipi_csi2.c   | 107 +++++++++---------
 .../sunxi/sun6i-mipi-csi2/sun6i_mipi_csi2.h   |   2 -
 2 files changed, 53 insertions(+), 56 deletions(-)

diff --git a/drivers/media/platform/sunxi/sun6i-mipi-csi2/sun6i_mipi_csi2.c b/drivers/media/platform/sunxi/sun6i-mipi-csi2/sun6i_mipi_csi2.c
index b06cb73015cd..682bdd82098c 100644
--- a/drivers/media/platform/sunxi/sun6i-mipi-csi2/sun6i_mipi_csi2.c
+++ b/drivers/media/platform/sunxi/sun6i-mipi-csi2/sun6i_mipi_csi2.c
@@ -95,12 +95,12 @@ static void sun6i_mipi_csi2_disable(struct sun6i_mipi_csi2_device *csi2_dev)
 			   SUN6I_MIPI_CSI2_CTL_EN, 0);
 }
 
-static void sun6i_mipi_csi2_configure(struct sun6i_mipi_csi2_device *csi2_dev)
+static void sun6i_mipi_csi2_configure(struct sun6i_mipi_csi2_device *csi2_dev,
+				       const struct v4l2_mbus_framefmt *mbus_format)
 {
 	struct regmap *regmap = csi2_dev->regmap;
 	unsigned int lanes_count =
 		csi2_dev->bridge.endpoint.bus.mipi_csi2.num_data_lanes;
-	struct v4l2_mbus_framefmt *mbus_format = &csi2_dev->bridge.mbus_format;
 	const struct sun6i_mipi_csi2_format *format;
 	struct device *dev = csi2_dev->dev;
 	u32 version = 0;
@@ -173,7 +173,8 @@ static int sun6i_mipi_csi2_s_stream(struct v4l2_subdev *subdev, int on)
 	struct v4l2_subdev *source_subdev = csi2_dev->bridge.source_subdev;
 	union phy_configure_opts dphy_opts = { 0 };
 	struct phy_configure_opts_mipi_dphy *dphy_cfg = &dphy_opts.mipi_dphy;
-	struct v4l2_mbus_framefmt *mbus_format = &csi2_dev->bridge.mbus_format;
+	struct v4l2_subdev_state *state;
+	const struct v4l2_mbus_framefmt *mbus_format;
 	const struct sun6i_mipi_csi2_format *format;
 	struct phy *dphy = csi2_dev->dphy;
 	struct device *dev = csi2_dev->dev;
@@ -183,8 +184,12 @@ static int sun6i_mipi_csi2_s_stream(struct v4l2_subdev *subdev, int on)
 	unsigned long pixel_rate;
 	int ret;
 
-	if (!source_subdev)
-		return -ENODEV;
+	state = v4l2_subdev_lock_and_get_active_state(subdev);
+
+	if (!source_subdev) {
+		ret = -ENODEV;
+		goto unlock;
+	}
 
 	if (!on) {
 		v4l2_subdev_call(source_subdev, video, s_stream, 0);
@@ -196,7 +201,7 @@ static int sun6i_mipi_csi2_s_stream(struct v4l2_subdev *subdev, int on)
 
 	ret = pm_runtime_resume_and_get(dev);
 	if (ret < 0)
-		return ret;
+		goto unlock;
 
 	/* Sensor Pixel Rate */
 
@@ -222,6 +227,8 @@ static int sun6i_mipi_csi2_s_stream(struct v4l2_subdev *subdev, int on)
 		goto error_pm;
 	}
 
+	mbus_format = v4l2_subdev_state_get_format(state,
+						   SUN6I_MIPI_CSI2_PAD_SINK);
 	format = sun6i_mipi_csi2_format_find(mbus_format->code);
 	if (WARN_ON(!format)) {
 		ret = -ENODEV;
@@ -260,7 +267,7 @@ static int sun6i_mipi_csi2_s_stream(struct v4l2_subdev *subdev, int on)
 
 	/* Controller */
 
-	sun6i_mipi_csi2_configure(csi2_dev);
+	sun6i_mipi_csi2_configure(csi2_dev, mbus_format);
 	sun6i_mipi_csi2_enable(csi2_dev);
 
 	/* D-PHY */
@@ -277,7 +284,8 @@ static int sun6i_mipi_csi2_s_stream(struct v4l2_subdev *subdev, int on)
 	if (ret && ret != -ENOIOCTLCMD)
 		goto disable;
 
-	return 0;
+	ret = 0;
+	goto unlock;
 
 disable:
 	phy_power_off(dphy);
@@ -286,6 +294,8 @@ static int sun6i_mipi_csi2_s_stream(struct v4l2_subdev *subdev, int on)
 error_pm:
 	pm_runtime_put(dev);
 
+unlock:
+	v4l2_subdev_unlock_state(state);
 	return ret;
 }
 
@@ -308,21 +318,23 @@ sun6i_mipi_csi2_mbus_format_prepare(struct v4l2_mbus_framefmt *mbus_format)
 static int sun6i_mipi_csi2_init_state(struct v4l2_subdev *subdev,
 				      struct v4l2_subdev_state *state)
 {
-	struct sun6i_mipi_csi2_device *csi2_dev = v4l2_get_subdevdata(subdev);
-	unsigned int pad = SUN6I_MIPI_CSI2_PAD_SINK;
-	struct v4l2_mbus_framefmt *mbus_format =
-		v4l2_subdev_state_get_format(state, pad);
-	struct mutex *lock = &csi2_dev->bridge.lock;
+	unsigned int pad;
 
-	mutex_lock(lock);
+	/*
+	 * This subdev does not perform format conversion,
+	 * initialize both pads identically.
+	 */
+	for (pad = 0; pad < subdev->entity.num_pads; pad++) {
+		struct v4l2_mbus_framefmt *mbus_format;
 
-	mbus_format->code = sun6i_mipi_csi2_formats[0].mbus_code;
-	mbus_format->width = 640;
-	mbus_format->height = 480;
+		mbus_format = v4l2_subdev_state_get_format(state, pad);
 
-	sun6i_mipi_csi2_mbus_format_prepare(mbus_format);
+		mbus_format->code = sun6i_mipi_csi2_formats[0].mbus_code;
+		mbus_format->width = 640;
+		mbus_format->height = 480;
 
-	mutex_unlock(lock);
+		sun6i_mipi_csi2_mbus_format_prepare(mbus_format);
+	}
 
 	return 0;
 }
@@ -340,53 +352,32 @@ sun6i_mipi_csi2_enum_mbus_code(struct v4l2_subdev *subdev,
 	return 0;
 }
 
-static int sun6i_mipi_csi2_get_fmt(struct v4l2_subdev *subdev,
-				   struct v4l2_subdev_state *state,
-				   struct v4l2_subdev_format *format)
-{
-	struct sun6i_mipi_csi2_device *csi2_dev = v4l2_get_subdevdata(subdev);
-	struct v4l2_mbus_framefmt *mbus_format = &format->format;
-	struct mutex *lock = &csi2_dev->bridge.lock;
-
-	mutex_lock(lock);
-
-	if (format->which == V4L2_SUBDEV_FORMAT_TRY)
-		*mbus_format = *v4l2_subdev_state_get_format(state,
-							     format->pad);
-	else
-		*mbus_format = csi2_dev->bridge.mbus_format;
-
-	mutex_unlock(lock);
-
-	return 0;
-}
-
 static int sun6i_mipi_csi2_set_fmt(struct v4l2_subdev *subdev,
 				   struct v4l2_subdev_state *state,
 				   struct v4l2_subdev_format *format)
 {
-	struct sun6i_mipi_csi2_device *csi2_dev = v4l2_get_subdevdata(subdev);
-	struct v4l2_mbus_framefmt *mbus_format = &format->format;
-	struct mutex *lock = &csi2_dev->bridge.lock;
+	struct v4l2_mbus_framefmt *fmt;
 
-	mutex_lock(lock);
+	/* The format on the source pad always matches the sink pad. */
+	if (format->pad != SUN6I_MIPI_CSI2_PAD_SINK)
+		return v4l2_subdev_get_fmt(subdev, state, format);
 
-	sun6i_mipi_csi2_mbus_format_prepare(mbus_format);
+	sun6i_mipi_csi2_mbus_format_prepare(&format->format);
 
-	if (format->which == V4L2_SUBDEV_FORMAT_TRY)
-		*v4l2_subdev_state_get_format(state, format->pad) =
-			*mbus_format;
-	else
-		csi2_dev->bridge.mbus_format = *mbus_format;
+	/* Set the format on the sink pad. */
+	fmt = v4l2_subdev_state_get_format(state, format->pad);
+	*fmt = format->format;
 
-	mutex_unlock(lock);
+	/* Propagate the format to the source pad. */
+	fmt = v4l2_subdev_state_get_format(state, SUN6I_MIPI_CSI2_PAD_SOURCE);
+	*fmt = format->format;
 
 	return 0;
 }
 
 static const struct v4l2_subdev_pad_ops sun6i_mipi_csi2_pad_ops = {
 	.enum_mbus_code	= sun6i_mipi_csi2_enum_mbus_code,
-	.get_fmt	= sun6i_mipi_csi2_get_fmt,
+	.get_fmt	= v4l2_subdev_get_fmt,
 	.set_fmt	= sun6i_mipi_csi2_set_fmt,
 };
 
@@ -502,8 +493,6 @@ static int sun6i_mipi_csi2_bridge_setup(struct sun6i_mipi_csi2_device *csi2_dev)
 	bool notifier_registered = false;
 	int ret;
 
-	mutex_init(&bridge->lock);
-
 	/* V4L2 Subdev */
 
 	v4l2_subdev_init(subdev, &sun6i_mipi_csi2_subdev_ops);
@@ -532,6 +521,12 @@ static int sun6i_mipi_csi2_bridge_setup(struct sun6i_mipi_csi2_device *csi2_dev)
 	if (ret)
 		return ret;
 
+	/* V4L2 Subdev finalize */
+
+	ret = v4l2_subdev_init_finalize(subdev);
+	if (ret < 0)
+		goto error_media_entity_cleanup;
+
 	/* V4L2 Async */
 
 	v4l2_async_subdev_nf_init(notifier, subdev);
@@ -565,6 +560,9 @@ static int sun6i_mipi_csi2_bridge_setup(struct sun6i_mipi_csi2_device *csi2_dev)
 error_v4l2_notifier_cleanup:
 	v4l2_async_nf_cleanup(notifier);
 
+	v4l2_subdev_cleanup(subdev);
+
+error_media_entity_cleanup:
 	media_entity_cleanup(&subdev->entity);
 
 	return ret;
@@ -579,6 +577,7 @@ sun6i_mipi_csi2_bridge_cleanup(struct sun6i_mipi_csi2_device *csi2_dev)
 	v4l2_async_unregister_subdev(subdev);
 	v4l2_async_nf_unregister(notifier);
 	v4l2_async_nf_cleanup(notifier);
+	v4l2_subdev_cleanup(subdev);
 	media_entity_cleanup(&subdev->entity);
 }
 
diff --git a/drivers/media/platform/sunxi/sun6i-mipi-csi2/sun6i_mipi_csi2.h b/drivers/media/platform/sunxi/sun6i-mipi-csi2/sun6i_mipi_csi2.h
index 24b15e34b5e8..d72dfbd6a993 100644
--- a/drivers/media/platform/sunxi/sun6i-mipi-csi2/sun6i_mipi_csi2.h
+++ b/drivers/media/platform/sunxi/sun6i-mipi-csi2/sun6i_mipi_csi2.h
@@ -32,8 +32,6 @@ struct sun6i_mipi_csi2_bridge {
 	struct media_pad		pads[SUN6I_MIPI_CSI2_PAD_COUNT];
 	struct v4l2_fwnode_endpoint	endpoint;
 	struct v4l2_async_notifier	notifier;
-	struct v4l2_mbus_framefmt	mbus_format;
-	struct mutex			lock; /* Mbus format lock. */
 
 	struct v4l2_subdev		*source_subdev;
 };
-- 
2.54.0



^ permalink raw reply related

* [PATCH 04/16] media: sun8i-a83t-mipi-csi2: Use V4L2 subdev active state
From: Paul Kocialkowski @ 2026-05-18 10:24 UTC (permalink / raw)
  To: linux-media, linux-arm-kernel, linux-sunxi, linux-kernel,
	linux-staging
  Cc: Paul Kocialkowski, Mauro Carvalho Chehab, Chen-Yu Tsai,
	Jernej Skrabec, Samuel Holland, Greg Kroah-Hartman, Arash Golgol,
	Laurent Pinchart, Nicolas Dufresne
In-Reply-To: <20260518102451.417971-1-paulk@sys-base.io>

From: Arash Golgol <arash.golgol@gmail.com>

Use the V4L2 subdev active state API to store the active format.
This simplifies the driver not only by dropping the bridge mbus_format
field, but it also allows dropping the bridge lock, replaced with
the state lock.

The sun8i-a83t-mipi-csi2 hardware does not perform any format
conversion. Enforce identical formats on the sink and source pads in
the set_fmt() and init_state() callbacks.

Signed-off-by: Arash Golgol <arash.golgol@gmail.com>
---
 .../sun8i_a83t_mipi_csi2.c                    | 113 +++++++++---------
 .../sun8i_a83t_mipi_csi2.h                    |   2 -
 2 files changed, 56 insertions(+), 59 deletions(-)

diff --git a/drivers/media/platform/sunxi/sun8i-a83t-mipi-csi2/sun8i_a83t_mipi_csi2.c b/drivers/media/platform/sunxi/sun8i-a83t-mipi-csi2/sun8i_a83t_mipi_csi2.c
index dbc51daa4fe3..2b7635f3952d 100644
--- a/drivers/media/platform/sunxi/sun8i-a83t-mipi-csi2/sun8i_a83t_mipi_csi2.c
+++ b/drivers/media/platform/sunxi/sun8i-a83t-mipi-csi2/sun8i_a83t_mipi_csi2.c
@@ -144,12 +144,12 @@ sun8i_a83t_mipi_csi2_disable(struct sun8i_a83t_mipi_csi2_device *csi2_dev)
 }
 
 static void
-sun8i_a83t_mipi_csi2_configure(struct sun8i_a83t_mipi_csi2_device *csi2_dev)
+sun8i_a83t_mipi_csi2_configure(struct sun8i_a83t_mipi_csi2_device *csi2_dev,
+			       const struct v4l2_mbus_framefmt *mbus_format)
 {
 	struct regmap *regmap = csi2_dev->regmap;
 	unsigned int lanes_count =
 		csi2_dev->bridge.endpoint.bus.mipi_csi2.num_data_lanes;
-	struct v4l2_mbus_framefmt *mbus_format = &csi2_dev->bridge.mbus_format;
 	const struct sun8i_a83t_mipi_csi2_format *format;
 	struct device *dev = csi2_dev->dev;
 	u32 version = 0;
@@ -205,7 +205,8 @@ static int sun8i_a83t_mipi_csi2_s_stream(struct v4l2_subdev *subdev, int on)
 	struct v4l2_subdev *source_subdev = csi2_dev->bridge.source_subdev;
 	union phy_configure_opts dphy_opts = { 0 };
 	struct phy_configure_opts_mipi_dphy *dphy_cfg = &dphy_opts.mipi_dphy;
-	struct v4l2_mbus_framefmt *mbus_format = &csi2_dev->bridge.mbus_format;
+	struct v4l2_subdev_state *state;
+	const struct v4l2_mbus_framefmt *mbus_format;
 	const struct sun8i_a83t_mipi_csi2_format *format;
 	struct phy *dphy = csi2_dev->dphy;
 	struct device *dev = csi2_dev->dev;
@@ -215,8 +216,12 @@ static int sun8i_a83t_mipi_csi2_s_stream(struct v4l2_subdev *subdev, int on)
 	unsigned long pixel_rate;
 	int ret;
 
-	if (!source_subdev)
-		return -ENODEV;
+	state = v4l2_subdev_lock_and_get_active_state(subdev);
+
+	if (!source_subdev) {
+		ret = -ENODEV;
+		goto unlock;
+	}
 
 	if (!on) {
 		v4l2_subdev_call(source_subdev, video, s_stream, 0);
@@ -228,7 +233,7 @@ static int sun8i_a83t_mipi_csi2_s_stream(struct v4l2_subdev *subdev, int on)
 
 	ret = pm_runtime_resume_and_get(dev);
 	if (ret < 0)
-		return ret;
+		goto unlock;
 
 	/* Sensor pixel rate */
 
@@ -254,6 +259,9 @@ static int sun8i_a83t_mipi_csi2_s_stream(struct v4l2_subdev *subdev, int on)
 		goto error_pm;
 	}
 
+	mbus_format =
+		v4l2_subdev_state_get_format(state,
+					     SUN8I_A83T_MIPI_CSI2_PAD_SINK);
 	format = sun8i_a83t_mipi_csi2_format_find(mbus_format->code);
 	if (WARN_ON(!format)) {
 		ret = -ENODEV;
@@ -292,7 +300,7 @@ static int sun8i_a83t_mipi_csi2_s_stream(struct v4l2_subdev *subdev, int on)
 
 	/* Controller */
 
-	sun8i_a83t_mipi_csi2_configure(csi2_dev);
+	sun8i_a83t_mipi_csi2_configure(csi2_dev, mbus_format);
 	sun8i_a83t_mipi_csi2_enable(csi2_dev);
 
 	/* D-PHY */
@@ -309,7 +317,8 @@ static int sun8i_a83t_mipi_csi2_s_stream(struct v4l2_subdev *subdev, int on)
 	if (ret && ret != -ENOIOCTLCMD)
 		goto disable;
 
-	return 0;
+	ret = 0;
+	goto unlock;
 
 disable:
 	phy_power_off(dphy);
@@ -318,6 +327,8 @@ static int sun8i_a83t_mipi_csi2_s_stream(struct v4l2_subdev *subdev, int on)
 error_pm:
 	pm_runtime_put(dev);
 
+unlock:
+	v4l2_subdev_unlock_state(state);
 	return ret;
 }
 
@@ -341,22 +352,24 @@ sun8i_a83t_mipi_csi2_mbus_format_prepare(struct v4l2_mbus_framefmt *mbus_format)
 static int sun8i_a83t_mipi_csi2_init_state(struct v4l2_subdev *subdev,
 					   struct v4l2_subdev_state *state)
 {
-	struct sun8i_a83t_mipi_csi2_device *csi2_dev =
-		v4l2_get_subdevdata(subdev);
-	unsigned int pad = SUN8I_A83T_MIPI_CSI2_PAD_SINK;
-	struct v4l2_mbus_framefmt *mbus_format =
-		v4l2_subdev_state_get_format(state, pad);
-	struct mutex *lock = &csi2_dev->bridge.lock;
+	unsigned int pad;
 
-	mutex_lock(lock);
+	/*
+	 * This subdev does not perform format conversion,
+	 * initialize both pads identically.
+	 */
+	for (pad = 0; pad < subdev->entity.num_pads; pad++) {
+		struct v4l2_mbus_framefmt *mbus_format;
 
-	mbus_format->code = sun8i_a83t_mipi_csi2_formats[0].mbus_code;
-	mbus_format->width = 640;
-	mbus_format->height = 480;
+		mbus_format = v4l2_subdev_state_get_format(state, pad);
+
+		mbus_format->code = sun8i_a83t_mipi_csi2_formats[0].mbus_code;
+		mbus_format->width = 640;
+		mbus_format->height = 480;
 
-	sun8i_a83t_mipi_csi2_mbus_format_prepare(mbus_format);
+		sun8i_a83t_mipi_csi2_mbus_format_prepare(mbus_format);
+	}
 
-	mutex_unlock(lock);
 
 	return 0;
 }
@@ -375,55 +388,33 @@ sun8i_a83t_mipi_csi2_enum_mbus_code(struct v4l2_subdev *subdev,
 	return 0;
 }
 
-static int sun8i_a83t_mipi_csi2_get_fmt(struct v4l2_subdev *subdev,
-					struct v4l2_subdev_state *state,
-					struct v4l2_subdev_format *format)
-{
-	struct sun8i_a83t_mipi_csi2_device *csi2_dev =
-		v4l2_get_subdevdata(subdev);
-	struct v4l2_mbus_framefmt *mbus_format = &format->format;
-	struct mutex *lock = &csi2_dev->bridge.lock;
-
-	mutex_lock(lock);
-
-	if (format->which == V4L2_SUBDEV_FORMAT_TRY)
-		*mbus_format = *v4l2_subdev_state_get_format(state,
-							     format->pad);
-	else
-		*mbus_format = csi2_dev->bridge.mbus_format;
-
-	mutex_unlock(lock);
-
-	return 0;
-}
-
 static int sun8i_a83t_mipi_csi2_set_fmt(struct v4l2_subdev *subdev,
 					struct v4l2_subdev_state *state,
 					struct v4l2_subdev_format *format)
 {
-	struct sun8i_a83t_mipi_csi2_device *csi2_dev =
-		v4l2_get_subdevdata(subdev);
-	struct v4l2_mbus_framefmt *mbus_format = &format->format;
-	struct mutex *lock = &csi2_dev->bridge.lock;
+	struct v4l2_mbus_framefmt *fmt;
 
-	mutex_lock(lock);
+	/* The format on the source pad always matches the sink pad. */
+	if (format->pad != SUN8I_A83T_MIPI_CSI2_PAD_SINK)
+		return v4l2_subdev_get_fmt(subdev, state, format);
 
-	sun8i_a83t_mipi_csi2_mbus_format_prepare(mbus_format);
+	sun8i_a83t_mipi_csi2_mbus_format_prepare(&format->format);
 
-	if (format->which == V4L2_SUBDEV_FORMAT_TRY)
-		*v4l2_subdev_state_get_format(state, format->pad) =
-			*mbus_format;
-	else
-		csi2_dev->bridge.mbus_format = *mbus_format;
+	/* Set the format on the sink pad. */
+	fmt = v4l2_subdev_state_get_format(state, format->pad);
+	*fmt = format->format;
 
-	mutex_unlock(lock);
+	/* Propagate the format to the source pad. */
+	fmt = v4l2_subdev_state_get_format(state,
+					   SUN8I_A83T_MIPI_CSI2_PAD_SOURCE);
+	*fmt = format->format;
 
 	return 0;
 }
 
 static const struct v4l2_subdev_pad_ops sun8i_a83t_mipi_csi2_pad_ops = {
 	.enum_mbus_code	= sun8i_a83t_mipi_csi2_enum_mbus_code,
-	.get_fmt	= sun8i_a83t_mipi_csi2_get_fmt,
+	.get_fmt	= v4l2_subdev_get_fmt,
 	.set_fmt	= sun8i_a83t_mipi_csi2_set_fmt,
 };
 
@@ -540,8 +531,6 @@ sun8i_a83t_mipi_csi2_bridge_setup(struct sun8i_a83t_mipi_csi2_device *csi2_dev)
 	bool notifier_registered = false;
 	int ret;
 
-	mutex_init(&bridge->lock);
-
 	/* V4L2 Subdev */
 
 	v4l2_subdev_init(subdev, &sun8i_a83t_mipi_csi2_subdev_ops);
@@ -570,6 +559,12 @@ sun8i_a83t_mipi_csi2_bridge_setup(struct sun8i_a83t_mipi_csi2_device *csi2_dev)
 	if (ret)
 		return ret;
 
+	/* V4L2 Subdev finalize */
+
+	ret = v4l2_subdev_init_finalize(subdev);
+	if (ret < 0)
+		goto error_media_entity_cleanup;
+
 	/* V4L2 Async */
 
 	v4l2_async_subdev_nf_init(notifier, subdev);
@@ -603,6 +598,9 @@ sun8i_a83t_mipi_csi2_bridge_setup(struct sun8i_a83t_mipi_csi2_device *csi2_dev)
 error_v4l2_notifier_cleanup:
 	v4l2_async_nf_cleanup(notifier);
 
+	v4l2_subdev_cleanup(subdev);
+
+error_media_entity_cleanup:
 	media_entity_cleanup(&subdev->entity);
 
 	return ret;
@@ -617,6 +615,7 @@ sun8i_a83t_mipi_csi2_bridge_cleanup(struct sun8i_a83t_mipi_csi2_device *csi2_dev
 	v4l2_async_unregister_subdev(subdev);
 	v4l2_async_nf_unregister(notifier);
 	v4l2_async_nf_cleanup(notifier);
+	v4l2_subdev_cleanup(subdev);
 	media_entity_cleanup(&subdev->entity);
 }
 
diff --git a/drivers/media/platform/sunxi/sun8i-a83t-mipi-csi2/sun8i_a83t_mipi_csi2.h b/drivers/media/platform/sunxi/sun8i-a83t-mipi-csi2/sun8i_a83t_mipi_csi2.h
index f1e64c53434c..819527bcd64d 100644
--- a/drivers/media/platform/sunxi/sun8i-a83t-mipi-csi2/sun8i_a83t_mipi_csi2.h
+++ b/drivers/media/platform/sunxi/sun8i-a83t-mipi-csi2/sun8i_a83t_mipi_csi2.h
@@ -33,8 +33,6 @@ struct sun8i_a83t_mipi_csi2_bridge {
 	struct media_pad		pads[SUN8I_A83T_MIPI_CSI2_PAD_COUNT];
 	struct v4l2_fwnode_endpoint	endpoint;
 	struct v4l2_async_notifier	notifier;
-	struct v4l2_mbus_framefmt	mbus_format;
-	struct mutex			lock; /* Mbus format lock. */
 
 	struct v4l2_subdev		*source_subdev;
 };
-- 
2.54.0



^ permalink raw reply related

* Re: [PATCH 2/2] firmware: samsung: acpm: add Exynos850 support
From: Tudor Ambarus @ 2026-05-18 10:27 UTC (permalink / raw)
  To: Alexey Klimov, Sam Protsenko, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Krzysztof Kozlowski, Alim Akhtar
  Cc: Peter Griffin, linux-samsung-soc, devicetree, linux-arm-kernel,
	linux-kernel
In-Reply-To: <20260513-exynos850-acpm-firmware-support-v1-2-3858d097e433@linaro.org>



On 5/13/26 2:12 AM, Alexey Klimov wrote:
> The Exynos850 SoC contains an APM co-processor. Communication
> with this hardware block is established using the ACPM protocol,
> which handles IPC messages for clocks, power, thermal management,
> and PMIC control.
> 
> Add the "samsung,exynos850-acpm-ipc" compatible string along with
> its associated match data. This includes the specific initialisation

s/initialisation/initialization 

> data base offset (which differs from the GS101 offset) and the
> "exynos850-acpm-clk" device name required to properly instantiate
> the clock provider.

The patch looks alright. With what client did you test it, cpufreq?

Reviewed-by: Tudor Ambarus <tudor.ambarus@linaro.org> 




^ permalink raw reply

* [PATCH 05/16] media: v4l2-common: Fix NV15_4L4 format info block height
From: Paul Kocialkowski @ 2026-05-18 10:24 UTC (permalink / raw)
  To: linux-media, linux-arm-kernel, linux-sunxi, linux-kernel,
	linux-staging
  Cc: Paul Kocialkowski, Mauro Carvalho Chehab, Chen-Yu Tsai,
	Jernej Skrabec, Samuel Holland, Greg Kroah-Hartman, Arash Golgol,
	Laurent Pinchart, Nicolas Dufresne
In-Reply-To: <20260518102451.417971-1-paulk@sys-base.io>

The NV15_4L4 format is specified as a 4x4 format, not 4x1.
In addition the block size should not take subsampling in account,
so specify it as 4x4 for both luma and chroma.

Signed-off-by: Paul Kocialkowski <paulk@sys-base.io>
---
 drivers/media/v4l2-core/v4l2-common.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/media/v4l2-core/v4l2-common.c b/drivers/media/v4l2-core/v4l2-common.c
index 554c591e1113..77a0daa92c2b 100644
--- a/drivers/media/v4l2-core/v4l2-common.c
+++ b/drivers/media/v4l2-core/v4l2-common.c
@@ -309,7 +309,7 @@ const struct v4l2_format_info *v4l2_format_info(u32 format)
 		/* Tiled YUV formats */
 		{ .format = V4L2_PIX_FMT_NV12_4L4, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 2, .bpp = { 1, 2, 0, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 2, .vdiv = 2 },
 		{ .format = V4L2_PIX_FMT_NV15_4L4, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 2, .bpp = { 5, 10, 0, 0 }, .bpp_div = { 4, 4, 1, 1 }, .hdiv = 2, .vdiv = 2,
-		  .block_w = { 4, 2, 0, 0 }, .block_h = { 1, 1, 0, 0 }},
+		  .block_w = { 4, 4, 0, 0 }, .block_h = { 4, 4, 0, 0 }},
 		{ .format = V4L2_PIX_FMT_P010_4L4, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 2, .bpp = { 2, 4, 0, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 2, .vdiv = 2 },
 
 		/* YUV planar formats, non contiguous variant */
-- 
2.54.0



^ permalink raw reply related

* Re: [PATCH v5 4/4] driver core: platform: set mod_name in driver registration
From: Greg Kroah-Hartman @ 2026-05-18 10:27 UTC (permalink / raw)
  To: Shashank Balaji
  Cc: Suzuki K Poulose, James Clark, Alexander Shishkin,
	Rafael J. Wysocki, Danilo Krummrich, Miguel Ojeda, Boqun Feng,
	Gary Guo, Björn Roy Baron, Benno Lossin, Andreas Hindborg,
	Alice Ryhl, Trevor Gross, Jonathan Corbet, Shuah Khan,
	Luis Chamberlain, Petr Pavlu, Daniel Gomez, Sami Tolvanen,
	Aaron Tomlin, Mike Leach, Leo Yan, Thierry Reding,
	Jonathan Hunter, Rahul Bukte, linux-kernel, coresight,
	linux-arm-kernel, driver-core, rust-for-linux, linux-doc,
	Daniel Palmer, Tim Bird, linux-modules, linux-tegra, Sumit Gupta
In-Reply-To: <20260518-acpi_mod_name-v5-4-705ccc430885@sony.com>

On Mon, May 18, 2026 at 07:20:00PM +0900, Shashank Balaji wrote:
> Pass KBUILD_MODNAME through the driver registration macro so that
> the driver core can create the module symlink in sysfs for built-in
> drivers, and fixup all callers.
> 
> The Rust platform adapter is updated to pass the module name through to the new
> parameter.
> 
> Tested on qemu with:
> - x86 defconfig + CONFIG_RUST
> - arm64 defconfig + CONFIG_RUST + CONFIG_CORESIGHT stuff
> 
> Examples after this patch:
> 
>     /sys/bus/platform/drivers/...
>         coresight-itnoc/module		-> coresight_tnoc
>         coresight-static-tpdm/module	-> coresight_tpdm
>         coresight-catu-platform/module	-> coresight_catu
>         serial8250/module		-> 8250
>         acpi-ged/module			-> acpi
>         vmclock/module			-> ptp_vmclock
> 
> Co-developed-by: Rahul Bukte <rahul.bukte@sony.com>
> Signed-off-by: Rahul Bukte <rahul.bukte@sony.com>
> Signed-off-by: Shashank Balaji <shashank.mahadasyam@sony.com>
> ---
> This patch depends on patches 1, 2, 3
> ---
>  Documentation/driver-api/driver-model/platform.rst |  3 ++-
>  drivers/base/platform.c                            | 21 ++++++++++++++-------
>  drivers/hwtracing/coresight/coresight-core.c       |  5 +++--
>  include/linux/coresight.h                          |  5 +++--
>  include/linux/platform_device.h                    | 17 +++++++++--------
>  rust/kernel/platform.rs                            |  4 +++-
>  6 files changed, 34 insertions(+), 21 deletions(-)
> 
> diff --git a/Documentation/driver-api/driver-model/platform.rst b/Documentation/driver-api/driver-model/platform.rst
> index cf5ff48d3115..9673470bded2 100644
> --- a/Documentation/driver-api/driver-model/platform.rst
> +++ b/Documentation/driver-api/driver-model/platform.rst
> @@ -70,7 +70,8 @@ Kernel modules can be composed of several platform drivers. The platform core
>  provides helpers to register and unregister an array of drivers::
>  
>  	int __platform_register_drivers(struct platform_driver * const *drivers,
> -				      unsigned int count, struct module *owner);
> +				      unsigned int count, struct module *owner,
> +				      const char *mod_name);

Why can't you just use the owner->name value instead?  They are always
the same here, right?

thanks,

greg k-h


^ permalink raw reply

* [PATCH 06/16] media: v4l2-common: Add missing tiled format info block sizes
From: Paul Kocialkowski @ 2026-05-18 10:24 UTC (permalink / raw)
  To: linux-media, linux-arm-kernel, linux-sunxi, linux-kernel,
	linux-staging
  Cc: Paul Kocialkowski, Mauro Carvalho Chehab, Chen-Yu Tsai,
	Jernej Skrabec, Samuel Holland, Greg Kroah-Hartman, Arash Golgol,
	Laurent Pinchart, Nicolas Dufresne
In-Reply-To: <20260518102451.417971-1-paulk@sys-base.io>

Some YUV420 tiled format info definitions are missing block sizes.
Add the missing block sizes (they are all 4x4).

Signed-off-by: Paul Kocialkowski <paulk@sys-base.io>
---
 drivers/media/v4l2-core/v4l2-common.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/media/v4l2-core/v4l2-common.c b/drivers/media/v4l2-core/v4l2-common.c
index 77a0daa92c2b..e142d40c71b9 100644
--- a/drivers/media/v4l2-core/v4l2-common.c
+++ b/drivers/media/v4l2-core/v4l2-common.c
@@ -307,10 +307,12 @@ const struct v4l2_format_info *v4l2_format_info(u32 format)
 		{ .format = V4L2_PIX_FMT_GREY,    .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 1, .bpp = { 1, 0, 0, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 1, .vdiv = 1 },
 
 		/* Tiled YUV formats */
-		{ .format = V4L2_PIX_FMT_NV12_4L4, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 2, .bpp = { 1, 2, 0, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 2, .vdiv = 2 },
+		{ .format = V4L2_PIX_FMT_NV12_4L4, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 2, .bpp = { 1, 2, 0, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 2, .vdiv = 2,
+		  .block_w = { 4, 4, 0, 0 }, .block_h = { 4, 4, 0, 0 }},
 		{ .format = V4L2_PIX_FMT_NV15_4L4, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 2, .bpp = { 5, 10, 0, 0 }, .bpp_div = { 4, 4, 1, 1 }, .hdiv = 2, .vdiv = 2,
 		  .block_w = { 4, 4, 0, 0 }, .block_h = { 4, 4, 0, 0 }},
-		{ .format = V4L2_PIX_FMT_P010_4L4, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 2, .bpp = { 2, 4, 0, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 2, .vdiv = 2 },
+		{ .format = V4L2_PIX_FMT_P010_4L4, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 2, .bpp = { 2, 4, 0, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 2, .vdiv = 2,
+		  .block_w = { 4, 4, 0, 0 }, .block_h = { 4, 4, 0, 0 }},
 
 		/* YUV planar formats, non contiguous variant */
 		{ .format = V4L2_PIX_FMT_YUV420M, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 3, .comp_planes = 3, .bpp = { 1, 1, 1, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 2, .vdiv = 2 },
-- 
2.54.0



^ permalink raw reply related

* [PATCH 07/16] media: v4l2-common: Add NV12_16L16 pixel format to v4l2 format info
From: Paul Kocialkowski @ 2026-05-18 10:24 UTC (permalink / raw)
  To: linux-media, linux-arm-kernel, linux-sunxi, linux-kernel,
	linux-staging
  Cc: Paul Kocialkowski, Mauro Carvalho Chehab, Chen-Yu Tsai,
	Jernej Skrabec, Samuel Holland, Greg Kroah-Hartman, Arash Golgol,
	Laurent Pinchart, Nicolas Dufresne
In-Reply-To: <20260518102451.417971-1-paulk@sys-base.io>

Represent the NV12_16L16 pixel format in the v4l2 format info table.
This is a 16x16 tiled version of NV12.

Signed-off-by: Paul Kocialkowski <paulk@sys-base.io>
---
 drivers/media/v4l2-core/v4l2-common.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/media/v4l2-core/v4l2-common.c b/drivers/media/v4l2-core/v4l2-common.c
index e142d40c71b9..6194d6eb9c56 100644
--- a/drivers/media/v4l2-core/v4l2-common.c
+++ b/drivers/media/v4l2-core/v4l2-common.c
@@ -313,6 +313,8 @@ const struct v4l2_format_info *v4l2_format_info(u32 format)
 		  .block_w = { 4, 4, 0, 0 }, .block_h = { 4, 4, 0, 0 }},
 		{ .format = V4L2_PIX_FMT_P010_4L4, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 2, .bpp = { 2, 4, 0, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 2, .vdiv = 2,
 		  .block_w = { 4, 4, 0, 0 }, .block_h = { 4, 4, 0, 0 }},
+		{ .format = V4L2_PIX_FMT_NV12_16L16,	.pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 2, .bpp = { 1, 2, 0, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 2, .vdiv = 2,
+		  .block_w = { 16, 16, 0, 0 }, .block_h = { 16, 16, 0, 0 }},
 
 		/* YUV planar formats, non contiguous variant */
 		{ .format = V4L2_PIX_FMT_YUV420M, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 3, .comp_planes = 3, .bpp = { 1, 1, 1, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 2, .vdiv = 2 },
-- 
2.54.0



^ permalink raw reply related

* [PATCH 08/16] media: v4l2-common: Add NV12_32L32 pixel format to v4l2 format info
From: Paul Kocialkowski @ 2026-05-18 10:24 UTC (permalink / raw)
  To: linux-media, linux-arm-kernel, linux-sunxi, linux-kernel,
	linux-staging
  Cc: Paul Kocialkowski, Mauro Carvalho Chehab, Chen-Yu Tsai,
	Jernej Skrabec, Samuel Holland, Greg Kroah-Hartman, Arash Golgol,
	Laurent Pinchart, Nicolas Dufresne
In-Reply-To: <20260518102451.417971-1-paulk@sys-base.io>

Represent the NV12_32L32 pixel format in the v4l2 format info table.
This is a 32x32 tiled version of NV12.

Signed-off-by: Paul Kocialkowski <paulk@sys-base.io>
---
 drivers/media/v4l2-core/v4l2-common.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/media/v4l2-core/v4l2-common.c b/drivers/media/v4l2-core/v4l2-common.c
index 6194d6eb9c56..fe7141883ec5 100644
--- a/drivers/media/v4l2-core/v4l2-common.c
+++ b/drivers/media/v4l2-core/v4l2-common.c
@@ -315,6 +315,8 @@ const struct v4l2_format_info *v4l2_format_info(u32 format)
 		  .block_w = { 4, 4, 0, 0 }, .block_h = { 4, 4, 0, 0 }},
 		{ .format = V4L2_PIX_FMT_NV12_16L16,	.pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 2, .bpp = { 1, 2, 0, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 2, .vdiv = 2,
 		  .block_w = { 16, 16, 0, 0 }, .block_h = { 16, 16, 0, 0 }},
+		{ .format = V4L2_PIX_FMT_NV12_32L32,	.pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 2, .bpp = { 1, 2, 0, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 2, .vdiv = 2,
+		  .block_w = { 32, 32, 0, 0 }, .block_h = { 32, 32, 0, 0 }},
 
 		/* YUV planar formats, non contiguous variant */
 		{ .format = V4L2_PIX_FMT_YUV420M, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 3, .comp_planes = 3, .bpp = { 1, 1, 1, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 2, .vdiv = 2 },
-- 
2.54.0



^ permalink raw reply related

* [PATCH 09/16] media: sun6i-csi: Split format validation to a dedicated helper
From: Paul Kocialkowski @ 2026-05-18 10:24 UTC (permalink / raw)
  To: linux-media, linux-arm-kernel, linux-sunxi, linux-kernel,
	linux-staging
  Cc: Paul Kocialkowski, Mauro Carvalho Chehab, Chen-Yu Tsai,
	Jernej Skrabec, Samuel Holland, Greg Kroah-Hartman, Arash Golgol,
	Laurent Pinchart, Nicolas Dufresne
In-Reply-To: <20260518102451.417971-1-paulk@sys-base.io>

Introduce a new sun6i_csi_capture_format_check helper based on the
link_validate code, which will be reused to implement MC-style
pixelformat enumeration.

Formats not listed in v4l2_format_info are now checked via
sun6i_csi_capture_format_check (which only concerns raw formats)
instead of blindly allowing them.

Also fix a comment in the raw format table.

Signed-off-by: Paul Kocialkowski <paulk@sys-base.io>
---
 .../sunxi/sun6i-csi/sun6i_csi_capture.c       | 87 +++++++++++--------
 1 file changed, 49 insertions(+), 38 deletions(-)

diff --git a/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi_capture.c b/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi_capture.c
index f788b4234673..a836fa7f081a 100644
--- a/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi_capture.c
+++ b/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi_capture.c
@@ -213,7 +213,7 @@ struct sun6i_csi_capture_format *sun6i_csi_capture_format_find(u32 pixelformat)
 /* RAW formats need an exact match between pixel and mbus formats. */
 static const
 struct sun6i_csi_capture_format_match sun6i_csi_capture_format_matches[] = {
-	/* YUV420 */
+	/* YUV422 */
 	{
 		.pixelformat	= V4L2_PIX_FMT_YUYV,
 		.mbus_code	= MEDIA_BUS_FMT_YUYV8_2X8,
@@ -327,6 +327,51 @@ static bool sun6i_csi_capture_format_match(u32 pixelformat, u32 mbus_code)
 	return false;
 }
 
+static bool
+sun6i_csi_capture_format_check(const struct sun6i_csi_capture_format *capture_format,
+			       const struct sun6i_csi_bridge_format *bridge_format)
+{
+	const struct v4l2_format_info *format_info;
+	u32 pixelformat = capture_format->pixelformat;
+	u32 mbus_code = bridge_format->mbus_code;
+	bool match;
+
+	format_info = v4l2_format_info(pixelformat);
+
+	/* Some raw formats like JPEG are not listed: try a direct match. */
+	if (!format_info)
+		return sun6i_csi_capture_format_match(pixelformat, mbus_code);
+
+	if (format_info->pixel_enc == V4L2_PIXEL_ENC_BAYER &&
+	    bridge_format->input_format != SUN6I_CSI_INPUT_FMT_RAW)
+		return false;
+
+	if (format_info->pixel_enc == V4L2_PIXEL_ENC_RGB &&
+	    bridge_format->input_format != SUN6I_CSI_INPUT_FMT_RAW)
+		return false;
+
+	if (format_info->pixel_enc == V4L2_PIXEL_ENC_YUV) {
+		if (bridge_format->input_format != SUN6I_CSI_INPUT_FMT_YUV420 &&
+		    bridge_format->input_format != SUN6I_CSI_INPUT_FMT_YUV422)
+			return false;
+
+		/* YUV420 input can't produce YUV422 output. */
+		if (bridge_format->input_format == SUN6I_CSI_INPUT_FMT_YUV420 &&
+		    format_info->vdiv == 1)
+			return false;
+	}
+
+	/* With raw input mode, we need a 1:1 match between input and output. */
+	if (bridge_format->input_format == SUN6I_CSI_INPUT_FMT_RAW ||
+	    capture_format->input_format_raw) {
+		match = sun6i_csi_capture_format_match(pixelformat, mbus_code);
+		if (!match)
+			return false;
+	}
+
+	return true;
+}
+
 /* Capture */
 
 static void
@@ -915,13 +960,11 @@ static int sun6i_csi_capture_link_validate(struct media_link *link)
 	const struct sun6i_csi_capture_format *capture_format;
 	const struct sun6i_csi_bridge_format *bridge_format;
 	unsigned int capture_width, capture_height;
-	const struct v4l2_format_info *format_info;
 	struct v4l2_subdev_format src_fmt = {
 		.which = V4L2_SUBDEV_FORMAT_ACTIVE,
 		.pad = link->source->index
 	};
 	u32 pixelformat, capture_field;
-	bool match;
 	int ret;
 
 	sun6i_csi_capture_dimensions(csi_dev, &capture_width, &capture_height);
@@ -950,44 +993,12 @@ static int sun6i_csi_capture_link_validate(struct media_link *link)
 		return -EINVAL;
 	}
 
-	format_info = v4l2_format_info(pixelformat);
-	/* Some formats are not listed. */
-	if (!format_info)
-		return 0;
-
-	if (format_info->pixel_enc == V4L2_PIXEL_ENC_BAYER &&
-	    bridge_format->input_format != SUN6I_CSI_INPUT_FMT_RAW)
-		goto invalid;
-
-	if (format_info->pixel_enc == V4L2_PIXEL_ENC_RGB &&
-	    bridge_format->input_format != SUN6I_CSI_INPUT_FMT_RAW)
-		goto invalid;
-
-	if (format_info->pixel_enc == V4L2_PIXEL_ENC_YUV) {
-		if (bridge_format->input_format != SUN6I_CSI_INPUT_FMT_YUV420 &&
-		    bridge_format->input_format != SUN6I_CSI_INPUT_FMT_YUV422)
-			goto invalid;
-
-		/* YUV420 input can't produce YUV422 output. */
-		if (bridge_format->input_format == SUN6I_CSI_INPUT_FMT_YUV420 &&
-		    format_info->vdiv == 1)
-			goto invalid;
-	}
-
-	/* With raw input mode, we need a 1:1 match between input and output. */
-	if (bridge_format->input_format == SUN6I_CSI_INPUT_FMT_RAW ||
-	    capture_format->input_format_raw) {
-		match = sun6i_csi_capture_format_match(pixelformat,
-						       src_fmt.format.code);
-		if (!match)
-			goto invalid;
+	if (!sun6i_csi_capture_format_check(capture_format, bridge_format)) {
+		v4l2_err(v4l2_dev, "invalid input/output format combination\n");
+		return -EINVAL;
 	}
 
 	return 0;
-
-invalid:
-	v4l2_err(v4l2_dev, "invalid input/output format combination\n");
-	return -EINVAL;
 }
 
 static const struct media_entity_operations sun6i_csi_capture_media_ops = {
-- 
2.54.0



^ permalink raw reply related

* [PATCH 10/16] media: sun6i-csi: Add support for MC-centric format enumeration
From: Paul Kocialkowski @ 2026-05-18 10:24 UTC (permalink / raw)
  To: linux-media, linux-arm-kernel, linux-sunxi, linux-kernel,
	linux-staging
  Cc: Paul Kocialkowski, Mauro Carvalho Chehab, Chen-Yu Tsai,
	Jernej Skrabec, Samuel Holland, Greg Kroah-Hartman, Arash Golgol,
	Laurent Pinchart, Nicolas Dufresne
In-Reply-To: <20260518102451.417971-1-paulk@sys-base.io>

Use the dedicated helper to check possible pixelformats against the
provided mbus code in order to support MC-centric format enumeration.

Note that multiple pixelformats may be returned for a given mbus code.

Signed-off-by: Paul Kocialkowski <paulk@sys-base.io>
---
 .../sunxi/sun6i-csi/sun6i_csi_capture.c       | 38 +++++++++++++++++--
 1 file changed, 34 insertions(+), 4 deletions(-)

diff --git a/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi_capture.c b/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi_capture.c
index a836fa7f081a..409c28621093 100644
--- a/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi_capture.c
+++ b/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi_capture.c
@@ -773,14 +773,43 @@ static int sun6i_csi_capture_querycap(struct file *file, void *priv,
 static int sun6i_csi_capture_enum_fmt(struct file *file, void *priv,
 				      struct v4l2_fmtdesc *fmtdesc)
 {
+	const struct sun6i_csi_capture_format *capture_format;
+	const struct sun6i_csi_bridge_format *bridge_format;
+	u32 mbus_code = fmtdesc->mbus_code;
 	u32 index = fmtdesc->index;
+	unsigned int index_valid = 0;
+	unsigned int i;
+
+	/* Video-node-centric enumeration. */
+	if (!mbus_code) {
+		if (index >= ARRAY_SIZE(sun6i_csi_capture_formats))
+			return -EINVAL;
+
+		fmtdesc->pixelformat =
+			sun6i_csi_capture_formats[index].pixelformat;
+		return 0;
+	}
 
-	if (index >= ARRAY_SIZE(sun6i_csi_capture_formats))
+	bridge_format = sun6i_csi_bridge_format_find(mbus_code);
+	if (!bridge_format)
 		return -EINVAL;
 
-	fmtdesc->pixelformat = sun6i_csi_capture_formats[index].pixelformat;
+	for (i = 0; i < ARRAY_SIZE(sun6i_csi_capture_formats); i++) {
+		capture_format = &sun6i_csi_capture_formats[i];
 
-	return 0;
+		if (!sun6i_csi_capture_format_check(capture_format,
+						    bridge_format))
+			continue;
+
+		if (index_valid == index) {
+			fmtdesc->pixelformat = capture_format->pixelformat;
+			return 0;
+		}
+
+		index_valid++;
+	}
+
+	return -EINVAL;
 }
 
 static int sun6i_csi_capture_enum_framesize(struct file *file, void *fh,
@@ -1076,7 +1105,8 @@ int sun6i_csi_capture_setup(struct sun6i_csi_device *csi_dev)
 
 	strscpy(video_dev->name, SUN6I_CSI_CAPTURE_NAME,
 		sizeof(video_dev->name));
-	video_dev->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING;
+	video_dev->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING |
+				 V4L2_CAP_IO_MC;
 	video_dev->vfl_dir = VFL_DIR_RX;
 	video_dev->release = video_device_release_empty;
 	video_dev->fops = &sun6i_csi_capture_fops;
-- 
2.54.0



^ permalink raw reply related

* [PATCH 11/16] media: sun6i-csi: Tidy up and unify coding style
From: Paul Kocialkowski @ 2026-05-18 10:24 UTC (permalink / raw)
  To: linux-media, linux-arm-kernel, linux-sunxi, linux-kernel,
	linux-staging
  Cc: Paul Kocialkowski, Mauro Carvalho Chehab, Chen-Yu Tsai,
	Jernej Skrabec, Samuel Holland, Greg Kroah-Hartman, Arash Golgol,
	Laurent Pinchart, Nicolas Dufresne
In-Reply-To: <20260518102451.417971-1-paulk@sys-base.io>

Bring recent changes to the same coding style as the rest of the driver.
This is purely cosmetic and no functional change is intended.

Signed-off-by: Paul Kocialkowski <paulk@sys-base.io>
---
 .../sunxi/sun6i-csi/sun6i_csi_bridge.c        | 16 ++---
 .../sunxi/sun6i-csi/sun6i_csi_capture.c       | 72 ++++++++++---------
 2 files changed, 46 insertions(+), 42 deletions(-)

diff --git a/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi_bridge.c b/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi_bridge.c
index 43a85bcc2ba2..18f79075d3ad 100644
--- a/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi_bridge.c
+++ b/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi_bridge.c
@@ -473,6 +473,7 @@ static int sun6i_csi_bridge_s_stream(struct v4l2_subdev *subdev, int on)
 
 unlock:
 	v4l2_subdev_unlock_state(state);
+
 	return ret;
 }
 
@@ -533,7 +534,7 @@ static int sun6i_csi_bridge_set_fmt(struct v4l2_subdev *subdev,
 				    struct v4l2_subdev_state *state,
 				    struct v4l2_subdev_format *format)
 {
-	struct v4l2_mbus_framefmt *fmt;
+	struct v4l2_mbus_framefmt *mbus_format;
 
 	/* The format on the source pad always matches the sink pad. */
 	if (format->pad != SUN6I_CSI_BRIDGE_PAD_SINK)
@@ -542,12 +543,12 @@ static int sun6i_csi_bridge_set_fmt(struct v4l2_subdev *subdev,
 	sun6i_csi_bridge_mbus_format_prepare(&format->format);
 
 	/* Set the format on the sink pad. */
-	fmt = v4l2_subdev_state_get_format(state, format->pad);
-	*fmt = format->format;
+	mbus_format = v4l2_subdev_state_get_format(state, format->pad);
+	*mbus_format = format->format;
 
 	/* Propagate the format to the source pad. */
-	fmt = v4l2_subdev_state_get_format(state, SUN6I_CSI_BRIDGE_PAD_SOURCE);
-	*fmt = format->format;
+	mbus_format = v4l2_subdev_state_get_format(state, SUN6I_CSI_BRIDGE_PAD_SOURCE);
+	*mbus_format = format->format;
 
 	return 0;
 }
@@ -779,14 +780,12 @@ int sun6i_csi_bridge_setup(struct sun6i_csi_device *csi_dev)
 	if (ret < 0)
 		return ret;
 
-	/* V4L2 Subdev finalize */
+	/* V4L2 Subdev */
 
 	ret = v4l2_subdev_init_finalize(subdev);
 	if (ret < 0)
 		goto error_media_entity;
 
-	/* V4L2 Subdev */
-
 	if (csi_dev->isp_available)
 		ret = v4l2_async_register_subdev(subdev);
 	else
@@ -846,7 +845,6 @@ void sun6i_csi_bridge_cleanup(struct sun6i_csi_device *csi_dev)
 	v4l2_async_nf_cleanup(notifier);
 
 	v4l2_device_unregister_subdev(subdev);
-
 	v4l2_subdev_cleanup(subdev);
 
 	media_entity_cleanup(&subdev->entity);
diff --git a/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi_capture.c b/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi_capture.c
index 409c28621093..eea682f47eea 100644
--- a/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi_capture.c
+++ b/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi_capture.c
@@ -812,27 +812,6 @@ static int sun6i_csi_capture_enum_fmt(struct file *file, void *priv,
 	return -EINVAL;
 }
 
-static int sun6i_csi_capture_enum_framesize(struct file *file, void *fh,
-					    struct v4l2_frmsizeenum *fsize)
-{
-	if (fsize->index)
-		return -EINVAL;
-
-	/* Only accept format in map table. */
-	if (!sun6i_csi_capture_format_find(fsize->pixel_format))
-		return -EINVAL;
-
-	fsize->type = V4L2_FRMSIZE_TYPE_STEPWISE;
-	fsize->stepwise.min_width = SUN6I_CSI_CAPTURE_WIDTH_MIN;
-	fsize->stepwise.max_width = SUN6I_CSI_CAPTURE_WIDTH_MAX;
-	fsize->stepwise.min_height = SUN6I_CSI_CAPTURE_HEIGHT_MIN;
-	fsize->stepwise.max_height = SUN6I_CSI_CAPTURE_HEIGHT_MAX;
-	fsize->stepwise.step_width = 2;
-	fsize->stepwise.step_height = 2;
-
-	return 0;
-}
-
 static int sun6i_csi_capture_g_fmt(struct file *file, void *priv,
 				   struct v4l2_format *format)
 {
@@ -867,6 +846,27 @@ static int sun6i_csi_capture_try_fmt(struct file *file, void *priv,
 	return 0;
 }
 
+static int sun6i_csi_capture_enum_framesizes(struct file *file, void *fh,
+					     struct v4l2_frmsizeenum *frmsize)
+{
+	if (frmsize->index)
+		return -EINVAL;
+
+	/* Only accept format in map table. */
+	if (!sun6i_csi_capture_format_find(frmsize->pixel_format))
+		return -EINVAL;
+
+	frmsize->type = V4L2_FRMSIZE_TYPE_STEPWISE;
+	frmsize->stepwise.min_width = SUN6I_CSI_CAPTURE_WIDTH_MIN;
+	frmsize->stepwise.max_width = SUN6I_CSI_CAPTURE_WIDTH_MAX;
+	frmsize->stepwise.min_height = SUN6I_CSI_CAPTURE_HEIGHT_MIN;
+	frmsize->stepwise.max_height = SUN6I_CSI_CAPTURE_HEIGHT_MAX;
+	frmsize->stepwise.step_width = 2;
+	frmsize->stepwise.step_height = 2;
+
+	return 0;
+}
+
 static int sun6i_csi_capture_enum_input(struct file *file, void *priv,
 					struct v4l2_input *input)
 {
@@ -900,11 +900,12 @@ static const struct v4l2_ioctl_ops sun6i_csi_capture_ioctl_ops = {
 	.vidioc_querycap		= sun6i_csi_capture_querycap,
 
 	.vidioc_enum_fmt_vid_cap	= sun6i_csi_capture_enum_fmt,
-	.vidioc_enum_framesizes		= sun6i_csi_capture_enum_framesize,
 	.vidioc_g_fmt_vid_cap		= sun6i_csi_capture_g_fmt,
 	.vidioc_s_fmt_vid_cap		= sun6i_csi_capture_s_fmt,
 	.vidioc_try_fmt_vid_cap		= sun6i_csi_capture_try_fmt,
 
+	.vidioc_enum_framesizes		= sun6i_csi_capture_enum_framesizes,
+
 	.vidioc_enum_input		= sun6i_csi_capture_enum_input,
 	.vidioc_g_input			= sun6i_csi_capture_g_input,
 	.vidioc_s_input			= sun6i_csi_capture_s_input,
@@ -984,16 +985,17 @@ static int sun6i_csi_capture_link_validate(struct media_link *link)
 		media_entity_to_video_device(link->sink->entity);
 	struct sun6i_csi_device *csi_dev = video_get_drvdata(video_dev);
 	struct v4l2_device *v4l2_dev = csi_dev->v4l2_dev;
-	struct v4l2_subdev *src_subdev =
+	struct v4l2_subdev *bridge_subdev =
 		media_entity_to_v4l2_subdev(link->source->entity);
 	const struct sun6i_csi_capture_format *capture_format;
 	const struct sun6i_csi_bridge_format *bridge_format;
 	unsigned int capture_width, capture_height;
-	struct v4l2_subdev_format src_fmt = {
-		.which = V4L2_SUBDEV_FORMAT_ACTIVE,
-		.pad = link->source->index
+	unsigned int bridge_width, bridge_height;
+	struct v4l2_subdev_format bridge_subdev_format = {
+		.which	= V4L2_SUBDEV_FORMAT_ACTIVE,
+		.pad	= link->source->index,
 	};
-	u32 pixelformat, capture_field;
+	u32 pixelformat, capture_field, mbus_code;
 	int ret;
 
 	sun6i_csi_capture_dimensions(csi_dev, &capture_width, &capture_height);
@@ -1004,21 +1006,25 @@ static int sun6i_csi_capture_link_validate(struct media_link *link)
 		return -EINVAL;
 
 	/* Resolve csi bridge format. */
-	ret = v4l2_subdev_call(src_subdev, pad, get_fmt, NULL, &src_fmt);
+	ret = v4l2_subdev_call(bridge_subdev, pad, get_fmt, NULL,
+			       &bridge_subdev_format);
 	if (ret)
 		return ret;
 
-	bridge_format = sun6i_csi_bridge_format_find(src_fmt.format.code);
+	bridge_width = bridge_subdev_format.format.width;
+	bridge_height = bridge_subdev_format.format.height;
+	mbus_code = bridge_subdev_format.format.code;
+
+	bridge_format = sun6i_csi_bridge_format_find(mbus_code);
 	if (WARN_ON(!bridge_format))
 		return -EINVAL;
 
 	/* No cropping/scaling is supported. */
-	if (capture_width != src_fmt.format.width ||
-	    capture_height != src_fmt.format.height) {
+	if (capture_width != bridge_width || capture_height != bridge_height) {
 		v4l2_err(v4l2_dev,
 			 "invalid input/output dimensions: %ux%u/%ux%u\n",
-			 src_fmt.format.width, src_fmt.format.height,
-			 capture_width, capture_height);
+			 bridge_width, bridge_height, capture_width,
+			 capture_height);
 		return -EINVAL;
 	}
 
-- 
2.54.0



^ permalink raw reply related

* [PATCH 12/16] media: sun6i-mipi-csi2: Fix parenthesis alignment
From: Paul Kocialkowski @ 2026-05-18 10:24 UTC (permalink / raw)
  To: linux-media, linux-arm-kernel, linux-sunxi, linux-kernel,
	linux-staging
  Cc: Paul Kocialkowski, Mauro Carvalho Chehab, Chen-Yu Tsai,
	Jernej Skrabec, Samuel Holland, Greg Kroah-Hartman, Arash Golgol,
	Laurent Pinchart, Nicolas Dufresne
In-Reply-To: <20260518102451.417971-1-paulk@sys-base.io>

This is purely cosmetic, no functional change intended.

Signed-off-by: Paul Kocialkowski <paulk@sys-base.io>
---
 drivers/media/platform/sunxi/sun6i-mipi-csi2/sun6i_mipi_csi2.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/media/platform/sunxi/sun6i-mipi-csi2/sun6i_mipi_csi2.c b/drivers/media/platform/sunxi/sun6i-mipi-csi2/sun6i_mipi_csi2.c
index 682bdd82098c..17a9a215a98a 100644
--- a/drivers/media/platform/sunxi/sun6i-mipi-csi2/sun6i_mipi_csi2.c
+++ b/drivers/media/platform/sunxi/sun6i-mipi-csi2/sun6i_mipi_csi2.c
@@ -96,7 +96,7 @@ static void sun6i_mipi_csi2_disable(struct sun6i_mipi_csi2_device *csi2_dev)
 }
 
 static void sun6i_mipi_csi2_configure(struct sun6i_mipi_csi2_device *csi2_dev,
-				       const struct v4l2_mbus_framefmt *mbus_format)
+				      const struct v4l2_mbus_framefmt *mbus_format)
 {
 	struct regmap *regmap = csi2_dev->regmap;
 	unsigned int lanes_count =
-- 
2.54.0



^ permalink raw reply related

* [PATCH 13/16] media: sun6i-isp: Add dummy params link_validate implementation
From: Paul Kocialkowski @ 2026-05-18 10:24 UTC (permalink / raw)
  To: linux-media, linux-arm-kernel, linux-sunxi, linux-kernel,
	linux-staging
  Cc: Paul Kocialkowski, Mauro Carvalho Chehab, Chen-Yu Tsai,
	Jernej Skrabec, Samuel Holland, Greg Kroah-Hartman, Arash Golgol,
	Laurent Pinchart, Nicolas Dufresne
In-Reply-To: <20260518102451.417971-1-paulk@sys-base.io>

There isn't anything configurable about the params video device link,
but the v4l2 core complains that no op is provided so implement a dummy
one to make it happy.

Signed-off-by: Paul Kocialkowski <paulk@sys-base.io>
---
 .../media/sunxi/sun6i-isp/sun6i_isp_params.c     | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)

diff --git a/drivers/staging/media/sunxi/sun6i-isp/sun6i_isp_params.c b/drivers/staging/media/sunxi/sun6i-isp/sun6i_isp_params.c
index 77c2d06c0436..b7ef33fa2b13 100644
--- a/drivers/staging/media/sunxi/sun6i-isp/sun6i_isp_params.c
+++ b/drivers/staging/media/sunxi/sun6i-isp/sun6i_isp_params.c
@@ -450,6 +450,18 @@ static const struct v4l2_file_operations sun6i_isp_params_fops = {
 	.poll		= vb2_fop_poll,
 };
 
+/* Media Entity */
+
+static int sun6i_isp_params_link_validate(struct media_link *link)
+{
+	/* Nothing to validate here. */
+	return 0;
+}
+
+static const struct media_entity_operations sun6i_isp_params_entity_ops = {
+	.link_validate	= sun6i_isp_params_link_validate,
+};
+
 /* Params */
 
 int sun6i_isp_params_setup(struct sun6i_isp_device *isp_dev)
@@ -470,6 +482,10 @@ int sun6i_isp_params_setup(struct sun6i_isp_device *isp_dev)
 	INIT_LIST_HEAD(&state->queue);
 	spin_lock_init(&state->lock);
 
+	/* Media Entity */
+
+	video_dev->entity.ops = &sun6i_isp_params_entity_ops;
+
 	/* Media Pads */
 
 	pad->flags = MEDIA_PAD_FL_SOURCE | MEDIA_PAD_FL_MUST_CONNECT;
-- 
2.54.0



^ permalink raw reply related

* [PATCH 14/16] media: sun6i-isp: Use V4L2 subdev active state
From: Paul Kocialkowski @ 2026-05-18 10:24 UTC (permalink / raw)
  To: linux-media, linux-arm-kernel, linux-sunxi, linux-kernel,
	linux-staging
  Cc: Paul Kocialkowski, Mauro Carvalho Chehab, Chen-Yu Tsai,
	Jernej Skrabec, Samuel Holland, Greg Kroah-Hartman, Arash Golgol,
	Laurent Pinchart, Nicolas Dufresne
In-Reply-To: <20260518102451.417971-1-paulk@sys-base.io>

Store the active format using the common V4L2 subdev active state
instead of our local copy of it.

Signed-off-by: Paul Kocialkowski <paulk@sys-base.io>
---
 .../media/sunxi/sun6i-isp/sun6i_isp_capture.c |  16 ++-
 .../media/sunxi/sun6i-isp/sun6i_isp_params.c  |  18 ++-
 .../media/sunxi/sun6i-isp/sun6i_isp_params.h  |   4 +-
 .../media/sunxi/sun6i-isp/sun6i_isp_proc.c    | 117 ++++++++----------
 .../media/sunxi/sun6i-isp/sun6i_isp_proc.h    |   7 --
 5 files changed, 82 insertions(+), 80 deletions(-)

diff --git a/drivers/staging/media/sunxi/sun6i-isp/sun6i_isp_capture.c b/drivers/staging/media/sunxi/sun6i-isp/sun6i_isp_capture.c
index e7b99cee63d6..24e731bcabe9 100644
--- a/drivers/staging/media/sunxi/sun6i-isp/sun6i_isp_capture.c
+++ b/drivers/staging/media/sunxi/sun6i-isp/sun6i_isp_capture.c
@@ -595,11 +595,25 @@ static int sun6i_isp_capture_link_validate(struct media_link *link)
 		media_entity_to_video_device(link->sink->entity);
 	struct sun6i_isp_device *isp_dev = video_get_drvdata(video_dev);
 	struct v4l2_device *v4l2_dev = &isp_dev->v4l2.v4l2_dev;
+	struct v4l2_subdev *proc_subdev =
+		media_entity_to_v4l2_subdev(link->source->entity);
 	unsigned int capture_width, capture_height;
 	unsigned int proc_width, proc_height;
+	struct v4l2_subdev_format proc_subdev_format = {
+		.which	= V4L2_SUBDEV_FORMAT_ACTIVE,
+		.pad	= link->source->index,
+	};
+	int ret;
 
 	sun6i_isp_capture_dimensions(isp_dev, &capture_width, &capture_height);
-	sun6i_isp_proc_dimensions(isp_dev, &proc_width, &proc_height);
+
+	ret = v4l2_subdev_call(proc_subdev, pad, get_fmt, NULL,
+			       &proc_subdev_format);
+	if (ret)
+		return ret;
+
+	proc_width = proc_subdev_format.format.width;
+	proc_height = proc_subdev_format.format.height;
 
 	/* No cropping/scaling is supported (yet). */
 	if (capture_width != proc_width || capture_height != proc_height) {
diff --git a/drivers/staging/media/sunxi/sun6i-isp/sun6i_isp_params.c b/drivers/staging/media/sunxi/sun6i-isp/sun6i_isp_params.c
index b7ef33fa2b13..0cc48e2bc8c6 100644
--- a/drivers/staging/media/sunxi/sun6i-isp/sun6i_isp_params.c
+++ b/drivers/staging/media/sunxi/sun6i-isp/sun6i_isp_params.c
@@ -43,11 +43,14 @@ static const struct sun6i_isp_params_config sun6i_isp_params_config_default = {
 	},
 };
 
-static void sun6i_isp_params_configure_ob(struct sun6i_isp_device *isp_dev)
+static void
+sun6i_isp_params_configure_ob(struct sun6i_isp_device *isp_dev,
+			      const struct v4l2_mbus_framefmt *mbus_format)
 {
 	unsigned int width, height;
 
-	sun6i_isp_proc_dimensions(isp_dev, &width, &height);
+	width = mbus_format->width;
+	height = mbus_format->height;
 
 	sun6i_isp_load_write(isp_dev, SUN6I_ISP_OB_SIZE_REG,
 			     SUN6I_ISP_OB_SIZE_WIDTH(width) |
@@ -112,10 +115,12 @@ static void sun6i_isp_params_configure_wb(struct sun6i_isp_device *isp_dev)
 			     SUN6I_ISP_WB_CFG_CLIP(0xfff));
 }
 
-static void sun6i_isp_params_configure_base(struct sun6i_isp_device *isp_dev)
+static void
+sun6i_isp_params_configure_base(struct sun6i_isp_device *isp_dev,
+				const struct v4l2_mbus_framefmt *mbus_format)
 {
 	sun6i_isp_params_configure_ae(isp_dev);
-	sun6i_isp_params_configure_ob(isp_dev);
+	sun6i_isp_params_configure_ob(isp_dev, mbus_format);
 	sun6i_isp_params_configure_wb(isp_dev);
 }
 
@@ -170,14 +175,15 @@ sun6i_isp_params_configure_modules(struct sun6i_isp_device *isp_dev,
 	sun6i_isp_load_write(isp_dev, SUN6I_ISP_MODULE_EN_REG, value);
 }
 
-void sun6i_isp_params_configure(struct sun6i_isp_device *isp_dev)
+void sun6i_isp_params_configure(struct sun6i_isp_device *isp_dev,
+				const struct v4l2_mbus_framefmt *mbus_format)
 {
 	struct sun6i_isp_params_state *state = &isp_dev->params.state;
 	unsigned long flags;
 
 	spin_lock_irqsave(&state->lock, flags);
 
-	sun6i_isp_params_configure_base(isp_dev);
+	sun6i_isp_params_configure_base(isp_dev, mbus_format);
 
 	/* Default config is only applied at the very first stream start. */
 	if (state->configured)
diff --git a/drivers/staging/media/sunxi/sun6i-isp/sun6i_isp_params.h b/drivers/staging/media/sunxi/sun6i-isp/sun6i_isp_params.h
index 50f10f879c42..c0d6cff95d54 100644
--- a/drivers/staging/media/sunxi/sun6i-isp/sun6i_isp_params.h
+++ b/drivers/staging/media/sunxi/sun6i-isp/sun6i_isp_params.h
@@ -36,8 +36,8 @@ struct sun6i_isp_params {
 
 /* Params */
 
-void sun6i_isp_params_configure(struct sun6i_isp_device *isp_dev);
-
+void sun6i_isp_params_configure(struct sun6i_isp_device *isp_dev,
+				const struct v4l2_mbus_framefmt *mbus_format);
 /* State */
 
 void sun6i_isp_params_state_update(struct sun6i_isp_device *isp_dev,
diff --git a/drivers/staging/media/sunxi/sun6i-isp/sun6i_isp_proc.c b/drivers/staging/media/sunxi/sun6i-isp/sun6i_isp_proc.c
index 46a334b602f1..9073a7f3f8c8 100644
--- a/drivers/staging/media/sunxi/sun6i-isp/sun6i_isp_proc.c
+++ b/drivers/staging/media/sunxi/sun6i-isp/sun6i_isp_proc.c
@@ -15,17 +15,6 @@
 #include "sun6i_isp_proc.h"
 #include "sun6i_isp_reg.h"
 
-/* Helpers */
-
-void sun6i_isp_proc_dimensions(struct sun6i_isp_device *isp_dev,
-			       unsigned int *width, unsigned int *height)
-{
-	if (width)
-		*width = isp_dev->proc.mbus_format.width;
-	if (height)
-		*height = isp_dev->proc.mbus_format.height;
-}
-
 /* Format */
 
 static const struct sun6i_isp_proc_format sun6i_isp_proc_formats[] = {
@@ -137,9 +126,10 @@ static void sun6i_isp_proc_disable(struct sun6i_isp_device *isp_dev)
 	regmap_write(regmap, SUN6I_ISP_FE_CFG_REG, 0);
 }
 
-static void sun6i_isp_proc_configure(struct sun6i_isp_device *isp_dev)
+static void
+sun6i_isp_proc_configure(struct sun6i_isp_device *isp_dev,
+			 const struct v4l2_mbus_framefmt *mbus_format)
 {
-	struct v4l2_mbus_framefmt *mbus_format = &isp_dev->proc.mbus_format;
 	const struct sun6i_isp_proc_format *format;
 	u32 value;
 
@@ -173,6 +163,8 @@ static int sun6i_isp_proc_s_stream(struct v4l2_subdev *subdev, int on)
 	struct sun6i_isp_proc_source *source;
 	struct v4l2_subdev *source_subdev;
 	struct media_pad *remote_pad;
+	struct v4l2_subdev_state *state;
+	const struct v4l2_mbus_framefmt *mbus_format;
 	int ret;
 
 	/* Source */
@@ -191,6 +183,10 @@ static int sun6i_isp_proc_s_stream(struct v4l2_subdev *subdev, int on)
 	else
 		source = &proc->source_csi1;
 
+	/* Active State */
+
+	state = v4l2_subdev_lock_and_get_active_state(subdev);
+
 	if (!on) {
 		sun6i_isp_proc_irq_disable(isp_dev);
 		v4l2_subdev_call(source_subdev, video, s_stream, 0);
@@ -202,7 +198,7 @@ static int sun6i_isp_proc_s_stream(struct v4l2_subdev *subdev, int on)
 
 	ret = pm_runtime_resume_and_get(dev);
 	if (ret < 0)
-		return ret;
+		goto unlock;
 
 	/* Clear */
 
@@ -210,9 +206,12 @@ static int sun6i_isp_proc_s_stream(struct v4l2_subdev *subdev, int on)
 
 	/* Configure */
 
+	mbus_format = v4l2_subdev_state_get_format(state,
+						   SUN6I_ISP_PROC_PAD_SINK_CSI);
+
 	sun6i_isp_tables_configure(isp_dev);
-	sun6i_isp_params_configure(isp_dev);
-	sun6i_isp_proc_configure(isp_dev);
+	sun6i_isp_params_configure(isp_dev, mbus_format);
+	sun6i_isp_proc_configure(isp_dev, mbus_format);
 	sun6i_isp_capture_configure(isp_dev);
 
 	/* State Update */
@@ -230,13 +229,17 @@ static int sun6i_isp_proc_s_stream(struct v4l2_subdev *subdev, int on)
 		goto disable;
 	}
 
-	return 0;
+	ret = 0;
+	goto unlock;
 
 disable:
 	sun6i_isp_proc_disable(isp_dev);
 
 	pm_runtime_put(dev);
 
+unlock:
+	v4l2_subdev_unlock_state(state);
+
 	return ret;
 }
 
@@ -259,21 +262,22 @@ sun6i_isp_proc_mbus_format_prepare(struct v4l2_mbus_framefmt *mbus_format)
 static int sun6i_isp_proc_init_state(struct v4l2_subdev *subdev,
 				     struct v4l2_subdev_state *state)
 {
-	struct sun6i_isp_device *isp_dev = v4l2_get_subdevdata(subdev);
-	unsigned int pad = SUN6I_ISP_PROC_PAD_SINK_CSI;
-	struct v4l2_mbus_framefmt *mbus_format =
-		v4l2_subdev_state_get_format(state, pad);
-	struct mutex *lock = &isp_dev->proc.lock;
+	unsigned int pad;
 
-	mutex_lock(lock);
+	for (pad = 0; pad < subdev->entity.num_pads; pad++) {
+		struct v4l2_mbus_framefmt *mbus_format;
 
-	mbus_format->code = sun6i_isp_proc_formats[0].mbus_code;
-	mbus_format->width = 1280;
-	mbus_format->height = 720;
+		if (pad == SUN6I_ISP_PROC_PAD_SINK_PARAMS)
+			continue;
 
-	sun6i_isp_proc_mbus_format_prepare(mbus_format);
+		mbus_format = v4l2_subdev_state_get_format(state, pad);
 
-	mutex_unlock(lock);
+		mbus_format->code = sun6i_isp_proc_formats[0].mbus_code;
+		mbus_format->width = 1280;
+		mbus_format->height = 720;
+
+		sun6i_isp_proc_mbus_format_prepare(mbus_format);
+	}
 
 	return 0;
 }
@@ -291,53 +295,31 @@ sun6i_isp_proc_enum_mbus_code(struct v4l2_subdev *subdev,
 	return 0;
 }
 
-static int sun6i_isp_proc_get_fmt(struct v4l2_subdev *subdev,
-				  struct v4l2_subdev_state *state,
-				  struct v4l2_subdev_format *format)
-{
-	struct sun6i_isp_device *isp_dev = v4l2_get_subdevdata(subdev);
-	struct v4l2_mbus_framefmt *mbus_format = &format->format;
-	struct mutex *lock = &isp_dev->proc.lock;
-
-	mutex_lock(lock);
-
-	if (format->which == V4L2_SUBDEV_FORMAT_TRY)
-		*mbus_format = *v4l2_subdev_state_get_format(state,
-							     format->pad);
-	else
-		*mbus_format = isp_dev->proc.mbus_format;
-
-	mutex_unlock(lock);
-
-	return 0;
-}
-
 static int sun6i_isp_proc_set_fmt(struct v4l2_subdev *subdev,
 				  struct v4l2_subdev_state *state,
 				  struct v4l2_subdev_format *format)
 {
-	struct sun6i_isp_device *isp_dev = v4l2_get_subdevdata(subdev);
-	struct v4l2_mbus_framefmt *mbus_format = &format->format;
-	struct mutex *lock = &isp_dev->proc.lock;
+	struct v4l2_mbus_framefmt *mbus_format;
 
-	mutex_lock(lock);
+	if (format->pad != SUN6I_ISP_PROC_PAD_SINK_CSI)
+		return v4l2_subdev_get_fmt(subdev, state, format);
 
-	sun6i_isp_proc_mbus_format_prepare(mbus_format);
+	sun6i_isp_proc_mbus_format_prepare(&format->format);
 
-	if (format->which == V4L2_SUBDEV_FORMAT_TRY)
-		*v4l2_subdev_state_get_format(state, format->pad) =
-			*mbus_format;
-	else
-		isp_dev->proc.mbus_format = *mbus_format;
+	mbus_format = v4l2_subdev_state_get_format(state, format->pad);
+	*mbus_format = format->format;
 
-	mutex_unlock(lock);
+	/* Propagate the format to the source pad. */
+	mbus_format = v4l2_subdev_state_get_format(state,
+						   SUN6I_ISP_PROC_PAD_SOURCE);
+	*mbus_format = format->format;
 
 	return 0;
 }
 
 static const struct v4l2_subdev_pad_ops sun6i_isp_proc_pad_ops = {
 	.enum_mbus_code	= sun6i_isp_proc_enum_mbus_code,
-	.get_fmt	= sun6i_isp_proc_get_fmt,
+	.get_fmt	= v4l2_subdev_get_fmt,
 	.set_fmt	= sun6i_isp_proc_set_fmt,
 };
 
@@ -499,8 +481,6 @@ int sun6i_isp_proc_setup(struct sun6i_isp_device *isp_dev)
 	struct media_pad *pads = proc->pads;
 	int ret;
 
-	mutex_init(&proc->lock);
-
 	/* V4L2 Subdev */
 
 	v4l2_subdev_init(subdev, &sun6i_isp_proc_subdev_ops);
@@ -532,10 +512,14 @@ int sun6i_isp_proc_setup(struct sun6i_isp_device *isp_dev)
 
 	/* V4L2 Subdev */
 
+	ret = v4l2_subdev_init_finalize(subdev);
+	if (ret < 0)
+		goto error_media_entity;
+
 	ret = v4l2_device_register_subdev(v4l2_dev, subdev);
 	if (ret < 0) {
 		v4l2_err(v4l2_dev, "failed to register v4l2 subdev: %d\n", ret);
-		goto error_media_entity;
+		goto error_subdev_finalize;
 	}
 
 	/* V4L2 Async */
@@ -562,6 +546,9 @@ int sun6i_isp_proc_setup(struct sun6i_isp_device *isp_dev)
 
 	v4l2_device_unregister_subdev(subdev);
 
+error_subdev_finalize:
+	v4l2_subdev_cleanup(subdev);
+
 error_media_entity:
 	media_entity_cleanup(&subdev->entity);
 
@@ -577,5 +564,7 @@ void sun6i_isp_proc_cleanup(struct sun6i_isp_device *isp_dev)
 	v4l2_async_nf_cleanup(notifier);
 
 	v4l2_device_unregister_subdev(subdev);
+	v4l2_subdev_cleanup(subdev);
+
 	media_entity_cleanup(&subdev->entity);
 }
diff --git a/drivers/staging/media/sunxi/sun6i-isp/sun6i_isp_proc.h b/drivers/staging/media/sunxi/sun6i-isp/sun6i_isp_proc.h
index db6738a39147..26c4327c5ed7 100644
--- a/drivers/staging/media/sunxi/sun6i-isp/sun6i_isp_proc.h
+++ b/drivers/staging/media/sunxi/sun6i-isp/sun6i_isp_proc.h
@@ -42,18 +42,11 @@ struct sun6i_isp_proc {
 	struct v4l2_subdev		subdev;
 	struct media_pad		pads[3];
 	struct v4l2_async_notifier	notifier;
-	struct v4l2_mbus_framefmt	mbus_format;
-	struct mutex			lock; /* Mbus format lock. */
 
 	struct sun6i_isp_proc_source	source_csi0;
 	struct sun6i_isp_proc_source	source_csi1;
 };
 
-/* Helpers */
-
-void sun6i_isp_proc_dimensions(struct sun6i_isp_device *isp_dev,
-			       unsigned int *width, unsigned int *height);
-
 /* Format */
 
 const struct sun6i_isp_proc_format *sun6i_isp_proc_format_find(u32 mbus_code);
-- 
2.54.0



^ permalink raw reply related

* Re: [PATCH v5 4/4] driver core: platform: set mod_name in driver registration
From: Shashank Balaji @ 2026-05-18 10:32 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: Suzuki K Poulose, James Clark, Alexander Shishkin,
	Rafael J. Wysocki, Danilo Krummrich, Miguel Ojeda, Boqun Feng,
	Gary Guo, Björn Roy Baron, Benno Lossin, Andreas Hindborg,
	Alice Ryhl, Trevor Gross, Jonathan Corbet, Shuah Khan,
	Luis Chamberlain, Petr Pavlu, Daniel Gomez, Sami Tolvanen,
	Aaron Tomlin, Mike Leach, Leo Yan, Thierry Reding,
	Jonathan Hunter, Rahul Bukte, linux-kernel, coresight,
	linux-arm-kernel, driver-core, rust-for-linux, linux-doc,
	Daniel Palmer, Tim Bird, linux-modules, linux-tegra, Sumit Gupta
In-Reply-To: <2026051827-curler-disjoin-c83f@gregkh>

On Mon, May 18, 2026 at 12:27:13PM +0200, Greg Kroah-Hartman wrote:
> On Mon, May 18, 2026 at 07:20:00PM +0900, Shashank Balaji wrote:
> > Pass KBUILD_MODNAME through the driver registration macro so that
> > the driver core can create the module symlink in sysfs for built-in
> > drivers, and fixup all callers.
> > 
> > The Rust platform adapter is updated to pass the module name through to the new
> > parameter.
> > 
> > Tested on qemu with:
> > - x86 defconfig + CONFIG_RUST
> > - arm64 defconfig + CONFIG_RUST + CONFIG_CORESIGHT stuff
> > 
> > Examples after this patch:
> > 
> >     /sys/bus/platform/drivers/...
> >         coresight-itnoc/module		-> coresight_tnoc
> >         coresight-static-tpdm/module	-> coresight_tpdm
> >         coresight-catu-platform/module	-> coresight_catu
> >         serial8250/module		-> 8250
> >         acpi-ged/module			-> acpi
> >         vmclock/module			-> ptp_vmclock
> > 
> > Co-developed-by: Rahul Bukte <rahul.bukte@sony.com>
> > Signed-off-by: Rahul Bukte <rahul.bukte@sony.com>
> > Signed-off-by: Shashank Balaji <shashank.mahadasyam@sony.com>
> > ---
> > This patch depends on patches 1, 2, 3
> > ---
> >  Documentation/driver-api/driver-model/platform.rst |  3 ++-
> >  drivers/base/platform.c                            | 21 ++++++++++++++-------
> >  drivers/hwtracing/coresight/coresight-core.c       |  5 +++--
> >  include/linux/coresight.h                          |  5 +++--
> >  include/linux/platform_device.h                    | 17 +++++++++--------
> >  rust/kernel/platform.rs                            |  4 +++-
> >  6 files changed, 34 insertions(+), 21 deletions(-)
> > 
> > diff --git a/Documentation/driver-api/driver-model/platform.rst b/Documentation/driver-api/driver-model/platform.rst
> > index cf5ff48d3115..9673470bded2 100644
> > --- a/Documentation/driver-api/driver-model/platform.rst
> > +++ b/Documentation/driver-api/driver-model/platform.rst
> > @@ -70,7 +70,8 @@ Kernel modules can be composed of several platform drivers. The platform core
> >  provides helpers to register and unregister an array of drivers::
> >  
> >  	int __platform_register_drivers(struct platform_driver * const *drivers,
> > -				      unsigned int count, struct module *owner);
> > +				      unsigned int count, struct module *owner,
> > +				      const char *mod_name);
> 
> Why can't you just use the owner->name value instead?  They are always
> the same here, right?

owner is NULL for built-in modules.


^ permalink raw reply

* [PATCH 15/16] media: sun6i-isp: Add support for MC-centric format enumeration
From: Paul Kocialkowski @ 2026-05-18 10:24 UTC (permalink / raw)
  To: linux-media, linux-arm-kernel, linux-sunxi, linux-kernel,
	linux-staging
  Cc: Paul Kocialkowski, Mauro Carvalho Chehab, Chen-Yu Tsai,
	Jernej Skrabec, Samuel Holland, Greg Kroah-Hartman, Arash Golgol,
	Laurent Pinchart, Nicolas Dufresne
In-Reply-To: <20260518102451.417971-1-paulk@sys-base.io>

Just make sure the provided mbus code is supported and carry on with the
existing implementation since the pixelformat is independent from the
mbus code.

The params video node only supports a single format and does not care
about the mbus format, but we can still report MC-centric support.

Signed-off-by: Paul Kocialkowski <paulk@sys-base.io>
---
 .../staging/media/sunxi/sun6i-isp/sun6i_isp_capture.c    | 9 ++++++++-
 drivers/staging/media/sunxi/sun6i-isp/sun6i_isp_params.c | 3 ++-
 2 files changed, 10 insertions(+), 2 deletions(-)

diff --git a/drivers/staging/media/sunxi/sun6i-isp/sun6i_isp_capture.c b/drivers/staging/media/sunxi/sun6i-isp/sun6i_isp_capture.c
index 24e731bcabe9..372b9331bd6d 100644
--- a/drivers/staging/media/sunxi/sun6i-isp/sun6i_isp_capture.c
+++ b/drivers/staging/media/sunxi/sun6i-isp/sun6i_isp_capture.c
@@ -436,8 +436,14 @@ static int sun6i_isp_capture_querycap(struct file *file, void *priv,
 static int sun6i_isp_capture_enum_fmt(struct file *file, void *priv,
 				      struct v4l2_fmtdesc *fmtdesc)
 {
+	u32 mbus_code = fmtdesc->mbus_code;
 	u32 index = fmtdesc->index;
 
+	if (mbus_code && !sun6i_isp_proc_format_find(mbus_code))
+		return -EINVAL;
+
+	/* Capture format is independent from proc format. */
+
 	if (index >= ARRAY_SIZE(sun6i_isp_capture_formats))
 		return -EINVAL;
 
@@ -697,7 +703,8 @@ int sun6i_isp_capture_setup(struct sun6i_isp_device *isp_dev)
 
 	strscpy(video_dev->name, SUN6I_ISP_CAPTURE_NAME,
 		sizeof(video_dev->name));
-	video_dev->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING;
+	video_dev->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING |
+				 V4L2_CAP_IO_MC;
 	video_dev->vfl_dir = VFL_DIR_RX;
 	video_dev->release = video_device_release_empty;
 	video_dev->fops = &sun6i_isp_capture_fops;
diff --git a/drivers/staging/media/sunxi/sun6i-isp/sun6i_isp_params.c b/drivers/staging/media/sunxi/sun6i-isp/sun6i_isp_params.c
index 0cc48e2bc8c6..2622e5a07817 100644
--- a/drivers/staging/media/sunxi/sun6i-isp/sun6i_isp_params.c
+++ b/drivers/staging/media/sunxi/sun6i-isp/sun6i_isp_params.c
@@ -531,7 +531,8 @@ int sun6i_isp_params_setup(struct sun6i_isp_device *isp_dev)
 
 	strscpy(video_dev->name, SUN6I_ISP_PARAMS_NAME,
 		sizeof(video_dev->name));
-	video_dev->device_caps = V4L2_CAP_META_OUTPUT | V4L2_CAP_STREAMING;
+	video_dev->device_caps = V4L2_CAP_META_OUTPUT | V4L2_CAP_STREAMING |
+				 V4L2_CAP_IO_MC;
 	video_dev->vfl_dir = VFL_DIR_TX;
 	video_dev->release = video_device_release_empty;
 	video_dev->fops = &sun6i_isp_params_fops;
-- 
2.54.0



^ permalink raw reply related

* Re: [PATCH 2/5] arm_mpam: Split the locking around the mon_sel registers
From: Niyas Sait @ 2026-05-18 10:31 UTC (permalink / raw)
  To: andre.przywara
  Cc: ben.horgan, catalin.marinas, fenghuay, guohanjun, james.morse,
	jic23, lenb, linux-acpi, linux-arm-kernel, linux-kernel,
	lpieralisi, rafael, reinette.chatre, sudeep.holla, will
In-Reply-To: <20260429141339.3171205-3-andre.przywara@arm.com>

Hi Andre,

On Wed, Apr 29, 2026 at 04:13:36PM +0200, Andre Przywara wrote:

> @@ -1635,8 +1643,11 @@ static int mpam_restore_mbwu_state(void *_ris)
>  	u64 val;
>  	struct mon_read mwbu_arg;
>  	struct mpam_msc_ris *ris = _ris;
> +	struct mpam_msc *msc = ris->vmsc->msc;
>  	struct mpam_class *class = ris->vmsc->comp->class;
>  
> +	mpam_mon_sel_outer_lock(msc);
> +
>  	for (i = 0; i < ris->props.num_mbwu_mon; i++) {
>  		if (ris->mbwu_state[i].enabled) {
>  			mwbu_arg.ris = ris;
> @@ -1648,10 +1659,12 @@ static int mpam_restore_mbwu_state(void *_ris)
>  		}
>  	}
>  
> +	mpam_mon_sel_outer_unlock(msc);
> +
>  	return 0;
>  }

There looks to be a lock nesting issue here. mpam_reprogram_msc() already
holds outer_mon_sel_lock when it calls mpam_restore_mbwu_state(), and
mpam_restore_mbwu_state() then takes the same outer lock again.

Thanks,
Niyas


^ permalink raw reply

* [PATCH 16/16] media: sun6i-isp: Add support for frame size enumeration
From: Paul Kocialkowski @ 2026-05-18 10:24 UTC (permalink / raw)
  To: linux-media, linux-arm-kernel, linux-sunxi, linux-kernel,
	linux-staging
  Cc: Paul Kocialkowski, Mauro Carvalho Chehab, Chen-Yu Tsai,
	Jernej Skrabec, Samuel Holland, Greg Kroah-Hartman, Arash Golgol,
	Laurent Pinchart, Nicolas Dufresne
In-Reply-To: <20260518102451.417971-1-paulk@sys-base.io>

This implements the enum_framesizes operation, which reports support for
even sizes.

Signed-off-by: Paul Kocialkowski <paulk@sys-base.io>
---
 .../media/sunxi/sun6i-isp/sun6i_isp_capture.c | 22 +++++++++++++++++++
 1 file changed, 22 insertions(+)

diff --git a/drivers/staging/media/sunxi/sun6i-isp/sun6i_isp_capture.c b/drivers/staging/media/sunxi/sun6i-isp/sun6i_isp_capture.c
index 372b9331bd6d..e638ec32c7cd 100644
--- a/drivers/staging/media/sunxi/sun6i-isp/sun6i_isp_capture.c
+++ b/drivers/staging/media/sunxi/sun6i-isp/sun6i_isp_capture.c
@@ -452,6 +452,26 @@ static int sun6i_isp_capture_enum_fmt(struct file *file, void *priv,
 	return 0;
 }
 
+static int sun6i_isp_capture_enum_framesizes(struct file *file, void *fh,
+					     struct v4l2_frmsizeenum *frmsize)
+{
+	if (frmsize->index)
+		return -EINVAL;
+
+	if (!sun6i_isp_capture_format_find(frmsize->pixel_format))
+		return -EINVAL;
+
+	frmsize->type = V4L2_FRMSIZE_TYPE_STEPWISE;
+	frmsize->stepwise.min_width = SUN6I_ISP_CAPTURE_WIDTH_MIN;
+	frmsize->stepwise.max_width = SUN6I_ISP_CAPTURE_WIDTH_MAX;
+	frmsize->stepwise.min_height = SUN6I_ISP_CAPTURE_HEIGHT_MIN;
+	frmsize->stepwise.max_height = SUN6I_ISP_CAPTURE_HEIGHT_MAX;
+	frmsize->stepwise.step_width = 2;
+	frmsize->stepwise.step_height = 2;
+
+	return 0;
+}
+
 static int sun6i_isp_capture_g_fmt(struct file *file, void *priv,
 				   struct v4l2_format *format)
 {
@@ -522,6 +542,8 @@ static const struct v4l2_ioctl_ops sun6i_isp_capture_ioctl_ops = {
 	.vidioc_s_fmt_vid_cap		= sun6i_isp_capture_s_fmt,
 	.vidioc_try_fmt_vid_cap		= sun6i_isp_capture_try_fmt,
 
+	.vidioc_enum_framesizes		= sun6i_isp_capture_enum_framesizes,
+
 	.vidioc_enum_input		= sun6i_isp_capture_enum_input,
 	.vidioc_g_input			= sun6i_isp_capture_g_input,
 	.vidioc_s_input			= sun6i_isp_capture_s_input,
-- 
2.54.0



^ permalink raw reply related

* Re: [PATCH v2 1/3] dt-bindings: arm: aspeed: add Anacapa EVT1 EVT2 board
From: Colin Huang @ 2026-05-18 10:43 UTC (permalink / raw)
  To: Conor Dooley
  Cc: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Joel Stanley,
	Andrew Jeffery, devicetree, linux-arm-kernel, linux-aspeed,
	linux-kernel, colin.huang2
In-Reply-To: <20260420-garnet-goal-4a284a8818fc@spud>

Conor Dooley <conor@kernel.org> 於 2026年4月20日週一 下午11:36寫道:
>
> On Mon, Apr 20, 2026 at 01:41:30PM +0800, Colin Huang wrote:
> > Conor Dooley <conor@kernel.org> 於 2026年4月9日週四 下午11:36寫道:
> > >
> > > On Thu, Apr 09, 2026 at 07:40:26PM +0800, Colin Huang wrote:
> > > > Document Anacapa BMC EVT1 and EVT2 compatibles.
> > > >
> > > > Signed-off-by: Colin Huang <u8813345@gmail.com>
> > >
> > > Acked-by: Conor Dooley <conor.dooley@microchip.com>
> > > pw-bot: not-applicable
> >
> > Hi
> >   Could anyone let me know, what is my next step which I need to do?
> >   I can't find the changed in for-next branch of
> > https://git.kernel.org/pub/scm/linux/kernel/git/bmc/linux.git .
> >   Thanks.
>
> You wait for the merge window to end and the maintainer to apply your
> patches.
Hi
soft-remind for these patches merge.


^ permalink raw reply

* Re: [PATCH 2/2] firmware: samsung: acpm: add Exynos850 support
From: Krzysztof Kozlowski @ 2026-05-18 10:46 UTC (permalink / raw)
  To: Tudor Ambarus, Alexey Klimov, Sam Protsenko, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Alim Akhtar
  Cc: Peter Griffin, linux-samsung-soc, devicetree, linux-arm-kernel,
	linux-kernel
In-Reply-To: <6802a856-76dc-4bd0-a026-59b0249646af@linaro.org>

On 18/05/2026 12:27, Tudor Ambarus wrote:
> 
> 
> On 5/13/26 2:12 AM, Alexey Klimov wrote:
>> The Exynos850 SoC contains an APM co-processor. Communication
>> with this hardware block is established using the ACPM protocol,
>> which handles IPC messages for clocks, power, thermal management,
>> and PMIC control.
>>
>> Add the "samsung,exynos850-acpm-ipc" compatible string along with
>> its associated match data. This includes the specific initialisation
> 
> s/initialisation/initialization 

Hoho, careful, that's a quite hot topic :)
I think we do not have kernel-wide preference here and even if there
was, no need to resend just for that.

Best regards,
Krzysztof


^ permalink raw reply

* Re: [PATCH 2/2] firmware: samsung: acpm: add Exynos850 support
From: Alexey Klimov @ 2026-05-18 10:46 UTC (permalink / raw)
  To: Tudor Ambarus, Sam Protsenko, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Krzysztof Kozlowski, Alim Akhtar
  Cc: Peter Griffin, linux-samsung-soc, devicetree, linux-arm-kernel,
	linux-kernel
In-Reply-To: <6802a856-76dc-4bd0-a026-59b0249646af@linaro.org>

On Mon May 18, 2026 at 11:27 AM BST, Tudor Ambarus wrote:
>
>
> On 5/13/26 2:12 AM, Alexey Klimov wrote:
>> The Exynos850 SoC contains an APM co-processor. Communication
>> with this hardware block is established using the ACPM protocol,
>> which handles IPC messages for clocks, power, thermal management,
>> and PMIC control.
>> 
>> Add the "samsung,exynos850-acpm-ipc" compatible string along with
>> its associated match data. This includes the specific initialisation
>
> s/initialisation/initialization 

Why? Where is the error here?

Also:
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/Documentation/doc-guide/contributing.rst?h=v7.1-rc4#n176

"Both American and British English spellings are allowed within the
kernel documentation.  There is no need to fix one by replacing it with
the other."

Also looking at git log, plenty of _s_ spellings.

>> data base offset (which differs from the GS101 offset) and the
>> "exynos850-acpm-clk" device name required to properly instantiate
>> the clock provider.
>
> The patch looks alright. With what client did you test it, cpufreq?
>
> Reviewed-by: Tudor Ambarus <tudor.ambarus@linaro.org> 

Thanks. As you might be aware this was tested with acpm-based tmu
and with dvfs/cpufreq both on e850-96. They are local changes here but I
can't send all of them in one go -- I need dependencies first.

Best regards,
Alexey


^ permalink raw reply

* Re: [PATCH v5 4/4] driver core: platform: set mod_name in driver registration
From: Greg Kroah-Hartman @ 2026-05-18 10:49 UTC (permalink / raw)
  To: Shashank Balaji
  Cc: Suzuki K Poulose, James Clark, Alexander Shishkin,
	Rafael J. Wysocki, Danilo Krummrich, Miguel Ojeda, Boqun Feng,
	Gary Guo, Björn Roy Baron, Benno Lossin, Andreas Hindborg,
	Alice Ryhl, Trevor Gross, Jonathan Corbet, Shuah Khan,
	Luis Chamberlain, Petr Pavlu, Daniel Gomez, Sami Tolvanen,
	Aaron Tomlin, Mike Leach, Leo Yan, Thierry Reding,
	Jonathan Hunter, Rahul Bukte, linux-kernel, coresight,
	linux-arm-kernel, driver-core, rust-for-linux, linux-doc,
	Daniel Palmer, Tim Bird, linux-modules, linux-tegra, Sumit Gupta
In-Reply-To: <agrqvIiNWrYtGvTk@JPC00244420>

On Mon, May 18, 2026 at 07:32:28PM +0900, Shashank Balaji wrote:
> On Mon, May 18, 2026 at 12:27:13PM +0200, Greg Kroah-Hartman wrote:
> > On Mon, May 18, 2026 at 07:20:00PM +0900, Shashank Balaji wrote:
> > > Pass KBUILD_MODNAME through the driver registration macro so that
> > > the driver core can create the module symlink in sysfs for built-in
> > > drivers, and fixup all callers.
> > > 
> > > The Rust platform adapter is updated to pass the module name through to the new
> > > parameter.
> > > 
> > > Tested on qemu with:
> > > - x86 defconfig + CONFIG_RUST
> > > - arm64 defconfig + CONFIG_RUST + CONFIG_CORESIGHT stuff
> > > 
> > > Examples after this patch:
> > > 
> > >     /sys/bus/platform/drivers/...
> > >         coresight-itnoc/module		-> coresight_tnoc
> > >         coresight-static-tpdm/module	-> coresight_tpdm
> > >         coresight-catu-platform/module	-> coresight_catu
> > >         serial8250/module		-> 8250
> > >         acpi-ged/module			-> acpi
> > >         vmclock/module			-> ptp_vmclock
> > > 
> > > Co-developed-by: Rahul Bukte <rahul.bukte@sony.com>
> > > Signed-off-by: Rahul Bukte <rahul.bukte@sony.com>
> > > Signed-off-by: Shashank Balaji <shashank.mahadasyam@sony.com>
> > > ---
> > > This patch depends on patches 1, 2, 3
> > > ---
> > >  Documentation/driver-api/driver-model/platform.rst |  3 ++-
> > >  drivers/base/platform.c                            | 21 ++++++++++++++-------
> > >  drivers/hwtracing/coresight/coresight-core.c       |  5 +++--
> > >  include/linux/coresight.h                          |  5 +++--
> > >  include/linux/platform_device.h                    | 17 +++++++++--------
> > >  rust/kernel/platform.rs                            |  4 +++-
> > >  6 files changed, 34 insertions(+), 21 deletions(-)
> > > 
> > > diff --git a/Documentation/driver-api/driver-model/platform.rst b/Documentation/driver-api/driver-model/platform.rst
> > > index cf5ff48d3115..9673470bded2 100644
> > > --- a/Documentation/driver-api/driver-model/platform.rst
> > > +++ b/Documentation/driver-api/driver-model/platform.rst
> > > @@ -70,7 +70,8 @@ Kernel modules can be composed of several platform drivers. The platform core
> > >  provides helpers to register and unregister an array of drivers::
> > >  
> > >  	int __platform_register_drivers(struct platform_driver * const *drivers,
> > > -				      unsigned int count, struct module *owner);
> > > +				      unsigned int count, struct module *owner,
> > > +				      const char *mod_name);
> > 
> > Why can't you just use the owner->name value instead?  They are always
> > the same here, right?
> 
> owner is NULL for built-in modules.

Ah, sorry, forgot about that.


^ permalink raw reply

* Re: [PATCH] drm/bridge: dw-hdmi-qp: compute audio CTS from N when not in TMDS table
From: Luca Ceresoli @ 2026-05-18 10:50 UTC (permalink / raw)
  To: Simon Wright, Cristian Ciocaltea
  Cc: Andrzej Hajda, Neil Armstrong, Robert Foss, Laurent Pinchart,
	Jonas Karlman, Jernej Skrabec, David Airlie, Simona Vetter,
	Heiko Stuebner, Andy Yan, Sebastian Reichel, Dmitry Baryshkov,
	Algea Cao, dri-devel, linux-rockchip, linux-arm-kernel,
	linux-kernel
In-Reply-To: <92aa4191-2a2a-41e3-badb-c0a5b1fbb957@symple.nz>

Hello Simon,

On Sat May 9, 2026 at 9:09 AM CEST, Simon Wright wrote:
> dw_hdmi_qp_find_cts() returns 0 for any TMDS character rate not
> present in common_tmds_cts_table[] (which terminates at 148.5 MHz).
> In that case dw_hdmi_qp_set_sample_rate() calls dw_hdmi_qp_set_cts_n()
> with cts == 0, which leaves AUDPKT_ACR_CTS_OVR_EN clear and falls
> back to the controller's internal CTS auto-measurement.
> On at least the RK3576 hdptx integration, strict HDMI sinks mute
> audio in this configuration.  The behaviour reproduces at any rate
> not present in the table -- it is not specific to HDMI 2.x:
> 1920x1080@60 with 10-bit deep colour (185.625 MHz, HDMI 1.4) is
> affected, as is 3840x2160@60 8-bit (594 MHz, HDMI 2.0).  Supplying
> explicit CTS via the standard set_cts_n() override path resolves
> the mute.
> The driver already has the symmetric machinery for the N-table-miss
> case: dw_hdmi_qp_compute_n() falls back to a dynamic search using
> dw_hdmi_qp_audio_math_diff() ((pixel_clk * n) / (128 * freq)) when
> no table entry matches.  The CTS path lacks the equivalent fallback.
> Compute CTS inline in dw_hdmi_qp_set_sample_rate() from N per the
> HDMI spec (CTS = TMDS * N / (128 * Fs)) when find_cts() returns 0.
> The same formula appears in the legacy DesignWare HDMI driver
> (drivers/gpu/drm/bridge/synopsys/dw-hdmi.c, hdmi_set_clk_regenerator())
> under its AHB / GP audio paths.
> Tested on R76S (RK3576) on Armbian-edge mainline 7.0.1 with Cristian
> Ciocaltea's hdptx-clk-fixes v1 series applied:
>    TMDS         Mode             In table?  Audio with fix
>    148.5 MHz    1080p60  8-bit   yes        plays (regression check)
>    185.625 MHz  1080p60 10-bit   no         plays
>    297 MHz      3840p30  8-bit   no         plays
>    594 MHz      3840p60  8-bit   no         plays
> Sinks tested: LG G3 OLED, LG C4 OLED, TCL 75P7K QLED, Kogan
> KALED43XU9210STA (Changhong-OEM 4K LED).  Without the fix, the LG
> G3 mutes audio -- this is the originally reported bug
> (linux-rockchip 070633).  The LG C4 was verified during this cycle
> to mute at 185.625 MHz (1080p60 10-bit) with the unpatched module.
> The Kogan TV plays audio with or without the fix; it is a
> permissive HDMI 2.0 implementation that does not strictly cross-
> check ACR timing.  The TCL 75P7K was tested with the fix loaded
> only.
> Audio plays at every supported sample rate (32 / 44.1 / 48 / 96 /
> 192 kHz) verified on the TCL at the 185.625 MHz out-of-table TMDS
> rate -- the fallback's CTS = (TMDS * N) / (128 * Fs) computation is
> independent of sample rate, as expected.
> The LG C4's CTA-861 SVDs do not advertise 3840x2160@60 over TMDS
> (it is signalled FRL-only on that model), so that one row is N/A
> on the C4.  The same audio-path code is exercised at 297 MHz on
> that sink and behaves identically to the G3.
> Reported-by: Simon Wright <simon@symple.nz>
> Closes:
> https://lists.infradead.org/pipermail/linux-rockchip/2026-May/070633.html
> Suggested-by: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
> Tested-by: Simon Wright <simon@symple.nz>
> Signed-off-by: Simon Wright <simon@symple.nz>
> ---
>   drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c | 15 +++++++++++++++
>   1 file changed, 15 insertions(+)
> diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c
> b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c
> index 0dbb1274360..25ac8d3cfc8 100644
> ---a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c
> +++b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c
> @@-461,6 +461,21 @@static void dw_hdmi_qp_set_sample_rate(struct
> dw_hdmi_qp *hdmi, unsigned long lo
>    n = dw_hdmi_qp_find_n(hdmi, tmds_char_rate, sample_rate);
>    cts = dw_hdmi_qp_find_cts(hdmi, tmds_char_rate, sample_rate);
> + /*
> +  * dw_hdmi_qp_find_cts() returns 0 for any TMDS rate not in
> +  * common_tmds_cts_table[].  Falling through to the controller's
> +  * auto-measure path mutes audio on strict HDMI sinks at out-of-
> +  * table rates (e.g. 185.625 MHz, 297 MHz, 594 MHz).  Compute CTS
> +  * from N per HDMI spec instead, so the standard override path
> +  * supplies it on the wire.
> +  */
> + if (!cts && n) {
> +   u64 computed = (u64)tmds_char_rate * n;
> +
> +   do_div(computed, 128ULL * sample_rate);
> +   cts = (unsigned int)computed;
> + }
> +
>    dw_hdmi_qp_set_cts_n(hdmi, cts, n);
>   }

Thanks for your patch. I cannot comment on the content but I can point for
formal issues with your submission.

Your patch got mangled by your mailer and cannot be applied. Please don't
try to convince your mailer to send patches the right way: save your time
and use "git-format patch + git send-email", or even better use b4.

Also your commit message is very detailed, and think it would be more
readable if split in paragraphs. You can have a look at various commits in
the kernel log for inspiration.

There's plenty of suggestions on how to send patches in [0], ensure you
read them all.

[0] https://docs.kernel.org/process/submitting-patches.html

Thanks!

Luca

--
Luca Ceresoli, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com


^ permalink raw reply

* [PATCH] media: rkvdec: fix PM runtime teardown ordering in remove
From: Francesco Saverio Pavone @ 2026-05-18 10:54 UTC (permalink / raw)
  To: jonas, detlev.casanova, nicolas.dufresne, hverkuil, mchehab
  Cc: ezequiel, heiko, linux-media, linux-rockchip, linux-arm-kernel,
	linux-kernel

From: Jonas Karlman <jonas@kwiboo.se>

The current remove() path calls rkvdec_v4l2_cleanup() and
pm_runtime_disable() before pm_runtime_dont_use_autosuspend(), and
frees the empty IOMMU domain after that. With autosuspend still
armed when the domain goes away, the VDPU381 can be left in a dirty
state across module reload and suspend/resume cycles.

On RK3588 this surfaces as a VP9 inter-prediction bug: from the
second ALTREF frame onward, motion blocks decode with U=V=0 (BT.709
green), while intra and static blocks stay correct. Reordering the
teardown to dont_use_autosuspend() -> iommu_domain_free() ->
pm_runtime_disable() -> v4l2_cleanup() makes the symptom go away.

Tested on a Radxa Rock 5B+ (RK3588, 8 GB LPDDR5) with both the
libva-v4l2-request mpv pipeline and Chromium's V4L2 stateless
decoder. With the fix, 300 random pixel samples on VP9 Profile 0
clips at 1080p and 1440p match a libvpx software reference exactly
(worst delta 0). Without it, the same 1080p sample at frame 4,
pixel (960, 270) reads HW=(0,112,0) vs SW=(204,147,116). HEVC and
H.264 stateless decoding via mpv keep running on hardware with no
fallback.

Fixes: ff8c5622f9f7 ("media: rkvdec: Restore iommu addresses on errors")
Signed-off-by: Jonas Karlman <jonas@kwiboo.se>
Tested-by: Francesco Saverio Pavone <pavone.lawyer@gmail.com>
Signed-off-by: Francesco Saverio Pavone <pavone.lawyer@gmail.com>
---
 drivers/media/platform/rockchip/rkvdec/rkvdec.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/media/platform/rockchip/rkvdec/rkvdec.c b/drivers/media/platform/rockchip/rkvdec/rkvdec.c
index 6f5f0422d317..bb95b090a25b 100644
--- a/drivers/media/platform/rockchip/rkvdec/rkvdec.c
+++ b/drivers/media/platform/rockchip/rkvdec/rkvdec.c
@@ -2066,12 +2066,13 @@ static void rkvdec_remove(struct platform_device *pdev)
 
 	cancel_delayed_work_sync(&rkvdec->watchdog_work);
 
-	rkvdec_v4l2_cleanup(rkvdec);
-	pm_runtime_disable(&pdev->dev);
 	pm_runtime_dont_use_autosuspend(&pdev->dev);
 
 	if (rkvdec->empty_domain)
 		iommu_domain_free(rkvdec->empty_domain);
+
+	pm_runtime_disable(&pdev->dev);
+	rkvdec_v4l2_cleanup(rkvdec);
 }
 
 #ifdef CONFIG_PM
-- 
2.45.0



^ permalink raw reply related


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