summaryrefslogtreecommitdiff
path: root/drivers/media/v4l2-core
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/v4l2-core')
-rw-r--r--drivers/media/v4l2-core/v4l2-async.c41
-rw-r--r--drivers/media/v4l2-core/v4l2-subdev.c13
2 files changed, 54 insertions, 0 deletions
diff --git a/drivers/media/v4l2-core/v4l2-async.c b/drivers/media/v4l2-core/v4l2-async.c
index 6b3c02d27ebf..ea27e04f0f75 100644
--- a/drivers/media/v4l2-core/v4l2-async.c
+++ b/drivers/media/v4l2-core/v4l2-async.c
@@ -134,6 +134,30 @@ static bool match_fwnode(struct v4l2_async_notifier *notifier,
"v4l2-async: matching for notifier %pfw, sd fwnode %pfw\n",
dev_fwnode(notifier_dev(notifier)), sd->fwnode);
+ if (!list_empty(&sd->async_subdev_endpoint_list)) {
+ struct v4l2_async_subdev_endpoint *ase;
+
+ dev_dbg(sd->dev,
+ "v4l2-async: endpoint fwnode list available, looking for %pfw\n",
+ match->fwnode);
+
+ list_for_each_entry(ase, &sd->async_subdev_endpoint_list,
+ async_subdev_endpoint_entry) {
+ bool matched = ase->endpoint == match->fwnode;
+
+ dev_dbg(sd->dev,
+ "v4l2-async: endpoint-endpoint match %sfound with %pfw\n",
+ matched ? "" : "not ", ase->endpoint);
+
+ if (matched)
+ return true;
+ }
+
+ dev_dbg(sd->dev, "async: no endpoint matched\n");
+
+ return false;
+ }
+
if (match_fwnode_one(notifier, sd, sd->fwnode, match))
return true;
@@ -745,6 +769,23 @@ __v4l2_async_nf_add_i2c(struct v4l2_async_notifier *notifier, int adapter_id,
}
EXPORT_SYMBOL_GPL(__v4l2_async_nf_add_i2c);
+int v4l2_async_subdev_endpoint_add(struct v4l2_subdev *sd,
+ struct fwnode_handle *fwnode)
+{
+ struct v4l2_async_subdev_endpoint *ase;
+
+ ase = kmalloc(sizeof(*ase), GFP_KERNEL);
+ if (!ase)
+ return -ENOMEM;
+
+ ase->endpoint = fwnode;
+ list_add(&ase->async_subdev_endpoint_entry,
+ &sd->async_subdev_endpoint_list);
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(v4l2_async_subdev_endpoint_add);
+
struct v4l2_async_connection *
v4l2_async_connection_unique(struct v4l2_subdev *sd)
{
diff --git a/drivers/media/v4l2-core/v4l2-subdev.c b/drivers/media/v4l2-core/v4l2-subdev.c
index 2ec179cd1264..217b8019fb9b 100644
--- a/drivers/media/v4l2-core/v4l2-subdev.c
+++ b/drivers/media/v4l2-core/v4l2-subdev.c
@@ -1467,8 +1467,20 @@ EXPORT_SYMBOL_GPL(__v4l2_subdev_init_finalize);
void v4l2_subdev_cleanup(struct v4l2_subdev *sd)
{
+ struct v4l2_async_subdev_endpoint *ase, *ase_tmp;
+
__v4l2_subdev_state_free(sd->active_state);
sd->active_state = NULL;
+
+ if (list_empty(&sd->async_subdev_endpoint_list))
+ return;
+
+ list_for_each_entry_safe(ase, ase_tmp, &sd->async_subdev_endpoint_list,
+ async_subdev_endpoint_entry) {
+ list_del(&ase->async_subdev_endpoint_entry);
+
+ kfree(ase);
+ }
}
EXPORT_SYMBOL_GPL(v4l2_subdev_cleanup);
@@ -2182,6 +2194,7 @@ void v4l2_subdev_init(struct v4l2_subdev *sd, const struct v4l2_subdev_ops *ops)
sd->dev_priv = NULL;
sd->host_priv = NULL;
sd->privacy_led = NULL;
+ INIT_LIST_HEAD(&sd->async_subdev_endpoint_list);
#if defined(CONFIG_MEDIA_CONTROLLER)
sd->entity.name = sd->name;
sd->entity.obj_type = MEDIA_ENTITY_TYPE_V4L2_SUBDEV;