diff options
Diffstat (limited to 'drivers/media/v4l2-core/v4l2-async.c')
-rw-r--r-- | drivers/media/v4l2-core/v4l2-async.c | 28 |
1 files changed, 26 insertions, 2 deletions
diff --git a/drivers/media/v4l2-core/v4l2-async.c b/drivers/media/v4l2-core/v4l2-async.c index 8d307b538f52..8bde33c21ce4 100644 --- a/drivers/media/v4l2-core/v4l2-async.c +++ b/drivers/media/v4l2-core/v4l2-async.c @@ -534,7 +534,7 @@ static void __v4l2_async_notifier_cleanup(struct v4l2_async_notifier *notifier) { struct v4l2_async_subdev *asd, *tmp; - if (!notifier) + if (!notifier || !notifier->asd_list.next) return; list_for_each_entry_safe(asd, tmp, ¬ifier->asd_list, asd_list) { @@ -593,10 +593,11 @@ v4l2_async_notifier_add_fwnode_subdev(struct v4l2_async_notifier *notifier, return ERR_PTR(-ENOMEM); asd->match_type = V4L2_ASYNC_MATCH_FWNODE; - asd->match.fwnode = fwnode; + asd->match.fwnode = fwnode_handle_get(fwnode); ret = v4l2_async_notifier_add_subdev(notifier, asd); if (ret) { + fwnode_handle_put(fwnode); kfree(asd); return ERR_PTR(ret); } @@ -605,6 +606,29 @@ v4l2_async_notifier_add_fwnode_subdev(struct v4l2_async_notifier *notifier, } EXPORT_SYMBOL_GPL(v4l2_async_notifier_add_fwnode_subdev); +int +v4l2_async_notifier_add_fwnode_remote_subdev(struct v4l2_async_notifier *notif, + struct fwnode_handle *endpoint, + struct v4l2_async_subdev *asd) +{ + struct fwnode_handle *remote; + int ret; + + remote = fwnode_graph_get_remote_port_parent(endpoint); + if (!remote) + return -ENOTCONN; + + asd->match_type = V4L2_ASYNC_MATCH_FWNODE; + asd->match.fwnode = remote; + + ret = v4l2_async_notifier_add_subdev(notif, asd); + if (ret) + fwnode_handle_put(remote); + + return ret; +} +EXPORT_SYMBOL_GPL(v4l2_async_notifier_add_fwnode_remote_subdev); + struct v4l2_async_subdev * v4l2_async_notifier_add_i2c_subdev(struct v4l2_async_notifier *notifier, int adapter_id, unsigned short address, |