summaryrefslogtreecommitdiff
path: root/drivers/media/v4l2-core/v4l2-async.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2022-08-03 19:29:28 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2022-08-03 19:29:28 -0700
commit12b68040a5e468068fd7f4af1150eab8f6e96235 (patch)
tree02b059a281615f4592a2d197c02a67ca110444fa /drivers/media/v4l2-core/v4l2-async.c
parent80dc75932ff231b05e0adbf5054bf4c9f0fb468c (diff)
parent485ade76c95ac5ccaa52fee9d712471c9211b989 (diff)
Merge tag 'media/v5.20-1' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media
Pull media updates from Mauro Carvalho Chehab: - New driver for Semi AR0521 sensor - rkisp1 CSI code was split into a separate file - sun6i has gained support for the A31 MIPI CSI-2 controller - sun8i has gained support for the A83T MIPI CSI-2 controller - vimc driver got support for virtual lens - HEVC uAPI has gained its final form and got added to public headers - hantro and cedrus got updates on H-265 support - stkwebcam was promoted from staging - atomisp staging driver got cleanups on its hmm and kmap related logic - ov5640 gained support for more modes and got some rework - imx7-media-csi staging driver got several improvements related to mc API support - uvcvideo now handles better power line control - mediatec vcodec gained support for new hardware and got some codec updates - Lots of other bug fixes, improvements and cleanups. * tag 'media/v5.20-1' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media: (446 commits) media: hantro: Remove dedicated control documentation hantro: Remove incorrect HEVC SPS validation media: cedrus: hevc: Add check for invalid timestamp media: sunxi: sun6i_mipi_csi2.c/sun8i_a83t_mipi_csi2.c: clarify error handling media: uvcvideo: Fix invalid pointer in uvc_ctrl_init_ctrl() media: Documentation: mc-core: Fix typo media: videodev2.h.rst.exceptions: add missing exceptions media: vimc: wrong pointer is used with PTR_ERR media: rkisp1: debug: Add dump file in debugfs for MI main path registers media: rkisp1: Make the internal CSI-2 receiver optional media: rkisp1: Add infrastructure to support ISP features media: rkisp1: Support the ISP parallel input media: dt-bindings: media: rkisp1: Add port for parallel interface media: rkisp1: Use fwnode_graph_for_each_endpoint media: rkisp1: csi: Plumb the CSI RX subdev media: rkisp1: csi: Implement a V4L2 subdev for the CSI receiver media: rkisp1: isp: Disallow multiple active sources media: rkisp1: isp: Rename rkisp1_get_remote_source() media: rkisp1: isp: Constify various local variables media: rkisp1: isp: Fix whitespace issues ...
Diffstat (limited to 'drivers/media/v4l2-core/v4l2-async.c')
-rw-r--r--drivers/media/v4l2-core/v4l2-async.c45
1 files changed, 31 insertions, 14 deletions
diff --git a/drivers/media/v4l2-core/v4l2-async.c b/drivers/media/v4l2-core/v4l2-async.c
index c6995718237a..2f1b718a9189 100644
--- a/drivers/media/v4l2-core/v4l2-async.c
+++ b/drivers/media/v4l2-core/v4l2-async.c
@@ -52,6 +52,15 @@ static int v4l2_async_nf_call_complete(struct v4l2_async_notifier *n)
return n->ops->complete(n);
}
+static void v4l2_async_nf_call_destroy(struct v4l2_async_notifier *n,
+ struct v4l2_async_subdev *asd)
+{
+ if (!n->ops || !n->ops->destroy)
+ return;
+
+ n->ops->destroy(asd);
+}
+
static bool match_i2c(struct v4l2_async_notifier *notifier,
struct v4l2_subdev *sd, struct v4l2_async_subdev *asd)
{
@@ -66,8 +75,10 @@ static bool match_i2c(struct v4l2_async_notifier *notifier,
#endif
}
-static bool match_fwnode(struct v4l2_async_notifier *notifier,
- struct v4l2_subdev *sd, struct v4l2_async_subdev *asd)
+static bool
+match_fwnode_one(struct v4l2_async_notifier *notifier,
+ struct v4l2_subdev *sd, struct fwnode_handle *sd_fwnode,
+ struct v4l2_async_subdev *asd)
{
struct fwnode_handle *other_fwnode;
struct fwnode_handle *dev_fwnode;
@@ -80,15 +91,7 @@ static bool match_fwnode(struct v4l2_async_notifier *notifier,
* fwnode or a device fwnode. Start with the simple case of direct
* fwnode matching.
*/
- if (sd->fwnode == asd->match.fwnode)
- return true;
-
- /*
- * Check the same situation for any possible secondary assigned to the
- * subdev's fwnode
- */
- if (!IS_ERR_OR_NULL(sd->fwnode->secondary) &&
- sd->fwnode->secondary == asd->match.fwnode)
+ if (sd_fwnode == asd->match.fwnode)
return true;
/*
@@ -99,7 +102,7 @@ static bool match_fwnode(struct v4l2_async_notifier *notifier,
* ACPI. This won't make a difference, as drivers should not try to
* match unconnected endpoints.
*/
- sd_fwnode_is_ep = fwnode_graph_is_endpoint(sd->fwnode);
+ sd_fwnode_is_ep = fwnode_graph_is_endpoint(sd_fwnode);
asd_fwnode_is_ep = fwnode_graph_is_endpoint(asd->match.fwnode);
if (sd_fwnode_is_ep == asd_fwnode_is_ep)
@@ -110,11 +113,11 @@ static bool match_fwnode(struct v4l2_async_notifier *notifier,
* parent of the endpoint fwnode, and compare it with the other fwnode.
*/
if (sd_fwnode_is_ep) {
- dev_fwnode = fwnode_graph_get_port_parent(sd->fwnode);
+ dev_fwnode = fwnode_graph_get_port_parent(sd_fwnode);
other_fwnode = asd->match.fwnode;
} else {
dev_fwnode = fwnode_graph_get_port_parent(asd->match.fwnode);
- other_fwnode = sd->fwnode;
+ other_fwnode = sd_fwnode;
}
fwnode_handle_put(dev_fwnode);
@@ -143,6 +146,19 @@ static bool match_fwnode(struct v4l2_async_notifier *notifier,
return true;
}
+static bool match_fwnode(struct v4l2_async_notifier *notifier,
+ struct v4l2_subdev *sd, struct v4l2_async_subdev *asd)
+{
+ if (match_fwnode_one(notifier, sd, sd->fwnode, asd))
+ return true;
+
+ /* Also check the secondary fwnode. */
+ if (IS_ERR_OR_NULL(sd->fwnode->secondary))
+ return false;
+
+ return match_fwnode_one(notifier, sd, sd->fwnode->secondary, asd);
+}
+
static LIST_HEAD(subdev_list);
static LIST_HEAD(notifier_list);
static DEFINE_MUTEX(list_lock);
@@ -626,6 +642,7 @@ static void __v4l2_async_nf_cleanup(struct v4l2_async_notifier *notifier)
}
list_del(&asd->asd_list);
+ v4l2_async_nf_call_destroy(notifier, asd);
kfree(asd);
}
}