Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
From b46c88f66951b03e155b98985f28b3d86e413179 Mon Sep 17 00:00:00 2001
From: "Yew, Chang Ching" <chang.ching.yew@intel.com>
Date: Thu, 22 Jan 2026 08:05:37 +0800
Subject: [PATCH 1/3] media: staging: ipu7-isys-csi2: get link frequency from
pad

In case driver does not have v4l2-control that stores link frequency,
try to retrieve link frequency from pad

Signed-off-by: Yew, Chang Ching <chang.ching.yew@intel.com>
---
drivers/staging/media/ipu7/ipu7-isys-csi2.c | 18 +++++++++++++++++-
1 file changed, 17 insertions(+), 1 deletion(-)

diff --git a/drivers/staging/media/ipu7/ipu7-isys-csi2.c b/drivers/staging/media/ipu7/ipu7-isys-csi2.c
index 9c16ae9a0e5bd..60e7856a5e2f9 100644
--- a/drivers/staging/media/ipu7/ipu7-isys-csi2.c
+++ b/drivers/staging/media/ipu7/ipu7-isys-csi2.c
@@ -51,6 +51,9 @@ static const u32 csi2_supported_codes[] = {
s64 ipu7_isys_csi2_get_link_freq(struct ipu7_isys_csi2 *csi2)
{
struct media_pad *src_pad;
+ struct v4l2_subdev *ext_sd;
+ struct device *dev;
+ s64 ret;

src_pad = media_entity_remote_source_pad_unique(&csi2->asd.sd.entity);
if (IS_ERR(src_pad)) {
@@ -60,7 +63,20 @@ s64 ipu7_isys_csi2_get_link_freq(struct ipu7_isys_csi2 *csi2)
return PTR_ERR(src_pad);
}

- return v4l2_get_link_freq(src_pad, 0, 0);
+ ext_sd = media_entity_to_v4l2_subdev(src_pad->entity);
+ if (WARN(!ext_sd, "Failed to get subdev for %s\n", csi2->asd.sd.name))
+ return -ENODEV;
+
+ ret = v4l2_get_link_freq(ext_sd->ctrl_handler, 0, 0);
+ if (ret < 0) {
+ ret = v4l2_get_link_freq(src_pad, 0, 0);
+ if (ret < 0) {
+ dev_err(dev, "Failed to get link frequency for %s\n",
+ csi2->asd.sd.name);
+ return ret;
+ }
+ }
+ return ret;
}

static int csi2_subscribe_event(struct v4l2_subdev *sd, struct v4l2_fh *fh,
--
2.51.1

Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
From ed73cafe221b2466def6568ba92f66d53a365207 Mon Sep 17 00:00:00 2001
From: "Yew, Chang Ching" <chang.ching.yew@intel.com>
Date: Thu, 22 Jan 2026 08:08:39 +0800
Subject: [PATCH 2/3] media: staging: ipu7: get source pad according to csi2 ep
fwnode

Signed-off-by: He, Pengpeng <pengpengx.he@intel.com>
Signed-off-by: Yew, Chang Ching <chang.ching.yew@intel.com>
---
drivers/staging/media/ipu7/ipu7-isys.c | 50 +++++++++++++++++++-------
drivers/staging/media/ipu7/ipu7-isys.h | 1 +
2 files changed, 39 insertions(+), 12 deletions(-)

diff --git a/drivers/staging/media/ipu7/ipu7-isys.c b/drivers/staging/media/ipu7/ipu7-isys.c
index 2bd8968a78cdf..74c45c3e7b5e4 100644
--- a/drivers/staging/media/ipu7/ipu7-isys.c
+++ b/drivers/staging/media/ipu7/ipu7-isys.c
@@ -55,23 +55,50 @@ isys_complete_ext_device_registration(struct ipu7_isys *isys,
struct ipu7_isys_csi2_config *csi2)
{
struct device *dev = &isys->adev->auxdev.dev;
- unsigned int i;
+ int source_pad;
int ret;

v4l2_set_subdev_hostdata(sd, csi2);

- for (i = 0; i < sd->entity.num_pads; i++) {
- if (sd->entity.pads[i].flags & MEDIA_PAD_FL_SOURCE)
- break;
- }
+ if (csi2->ep) {
+ struct fwnode_handle *ep_source;

- if (i == sd->entity.num_pads) {
- dev_warn(dev, "no source pad in external entity\n");
- ret = -ENOENT;
- goto skip_unregister_subdev;
+ ep_source = fwnode_graph_get_remote_endpoint(csi2->ep);
+ if (!ep_source) {
+ dev_warn(dev, "no remote endpoint for subdev\n");
+ ret = -ENOENT;
+ goto skip_unregister_subdev;
+ }
+
+ source_pad = media_entity_get_fwnode_pad(&sd->entity, ep_source,
+ MEDIA_PAD_FL_SOURCE);
+
+ if (source_pad < 0) {
+ dev_warn(dev, "error in no acquire source pad in external entity\n");
+ ret = -ENOENT;
+ goto skip_unregister_subdev;
+ }
+
+ dev_dbg(&isys->adev->auxdev.dev, "%s: CSI2 ep %pfw\n", __func__,
+ csi2->ep);
+ dev_dbg(&isys->adev->auxdev.dev,
+ "%s: source pad %d for subdev %s\n", __func__, source_pad,
+ sd->name);
+
+ fwnode_handle_put(ep_source);
+ } else {
+ for (source_pad = 0; source_pad < sd->entity.num_pads; source_pad++) {
+ if (sd->entity.pads[source_pad].flags & MEDIA_PAD_FL_SOURCE)
+ break;
+ }
+ if (source_pad == sd->entity.num_pads) {
+ dev_warn(dev, "no source pad in external entity\n");
+ ret = -ENOENT;
+ goto skip_unregister_subdev;
+ }
}

- ret = media_create_pad_link(&sd->entity, i,
+ ret = media_create_pad_link(&sd->entity, source_pad,
&isys->csi2[csi2->port].asd.sd.entity,
0, MEDIA_LNK_FL_ENABLED |
MEDIA_LNK_FL_IMMUTABLE);
@@ -226,8 +253,7 @@ static int isys_notifier_init(struct ipu7_isys *isys)
s_asd->csi2.port = vep.base.port;
s_asd->csi2.nlanes = vep.bus.mipi_csi2.num_data_lanes;
s_asd->csi2.bus_type = vep.bus_type;
-
- fwnode_handle_put(ep);
+ s_asd->csi2.ep = ep;

continue;

diff --git a/drivers/staging/media/ipu7/ipu7-isys.h b/drivers/staging/media/ipu7/ipu7-isys.h
index 17d4d56301691..55afb5b6e2d94 100644
--- a/drivers/staging/media/ipu7/ipu7-isys.h
+++ b/drivers/staging/media/ipu7/ipu7-isys.h
@@ -141,6 +141,7 @@ struct ipu7_isys_csi2_config {
unsigned int nlanes;
unsigned int port;
enum v4l2_mbus_type bus_type;
+ struct fwnode_handle *ep;
};

struct sensor_async_sd {
--
2.51.1

Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
From c15faaa1927bd9aa2a690822cc147e12f47a10cd Mon Sep 17 00:00:00 2001
From: hepengpx <pengpengx.he@intel.com>
Date: Wed, 17 Dec 2025 15:22:07 +0800
Subject: [PATCH 3/3] media: ipu7: Clean csi2 fwnode ep when destroying
v4l2_async_connection

Signed-off-by: hepengpx <pengpengx.he@intel.com>
Signed-off-by: Yew, Chang Ching <chang.ching.yew@intel.com>
---
drivers/staging/media/ipu7/ipu7-isys.c | 9 +++++++++
1 file changed, 9 insertions(+)

diff --git a/drivers/staging/media/ipu7/ipu7-isys.c b/drivers/staging/media/ipu7/ipu7-isys.c
index 74c45c3e7b5e4..d3de8ba02e9d6 100644
--- a/drivers/staging/media/ipu7/ipu7-isys.c
+++ b/drivers/staging/media/ipu7/ipu7-isys.c
@@ -202,9 +202,18 @@ static int isys_notifier_complete(struct v4l2_async_notifier *notifier)
return v4l2_device_register_subdev_nodes(&isys->v4l2_dev);
}

+static void isys_notifier_destroy(struct v4l2_async_connection *asc)
+{
+ struct sensor_async_sd *s_asd =
+ container_of(asc, struct sensor_async_sd, asc);
+
+ fwnode_handle_put(s_asd->csi2.ep);
+}
+
static const struct v4l2_async_notifier_operations isys_async_ops = {
.bound = isys_notifier_bound,
.complete = isys_notifier_complete,
+ .destroy = isys_notifier_destroy,
};

static int isys_notifier_init(struct ipu7_isys *isys)
--
2.51.1