mirror of https://gitee.com/openkylin/linux.git
media: v4l2-async: Get fwnode reference when putting it to the notifier's list
The v4l2_async_notifier_add_fwnode_subdev() did not take a reference of the added fwnode, relying on the caller to handle that instead, in essence putting the fwnode to be added if there was an error. As the reference is eventually released during the notifier cleanup, this is not intuitive nor logical. Improve this by always getting a reference when the function succeeds, and the caller releasing the reference when it does not *itself* need it anymore. Luckily, perhaps, there were just a handful of callers using the function. Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com> Reviewed-by: Jacopo Mondi <jacopo+renesas@jmondi.org> Tested-by: Niklas Söderlund <niklas.soderlund+renesas@ragnatech.se> Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
This commit is contained in:
parent
6a76404b13
commit
016413d967
|
@ -2489,10 +2489,9 @@ vpfe_get_pdata(struct vpfe_device *vpfe)
|
|||
pdata->asd[i] = v4l2_async_notifier_add_fwnode_subdev(
|
||||
&vpfe->notifier, of_fwnode_handle(rem),
|
||||
sizeof(struct v4l2_async_subdev));
|
||||
if (IS_ERR(pdata->asd[i])) {
|
||||
of_node_put(rem);
|
||||
of_node_put(rem);
|
||||
if (IS_ERR(pdata->asd[i]))
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
|
||||
of_node_put(endpoint);
|
||||
|
|
|
@ -1502,6 +1502,7 @@ static struct vpif_capture_config *
|
|||
vpif_capture_get_pdata(struct platform_device *pdev)
|
||||
{
|
||||
struct device_node *endpoint = NULL;
|
||||
struct device_node *rem = NULL;
|
||||
struct vpif_capture_config *pdata;
|
||||
struct vpif_subdev_info *sdinfo;
|
||||
struct vpif_capture_chan_config *chan;
|
||||
|
@ -1532,7 +1533,6 @@ vpif_capture_get_pdata(struct platform_device *pdev)
|
|||
|
||||
for (i = 0; i < VPIF_CAPTURE_NUM_CHANNELS; i++) {
|
||||
struct v4l2_fwnode_endpoint bus_cfg = { .bus_type = 0 };
|
||||
struct device_node *rem;
|
||||
unsigned int flags;
|
||||
int err;
|
||||
|
||||
|
@ -1554,10 +1554,8 @@ vpif_capture_get_pdata(struct platform_device *pdev)
|
|||
VPIF_CAPTURE_NUM_CHANNELS,
|
||||
sizeof(*chan->inputs),
|
||||
GFP_KERNEL);
|
||||
if (!chan->inputs) {
|
||||
of_node_put(rem);
|
||||
if (!chan->inputs)
|
||||
goto err_cleanup;
|
||||
}
|
||||
|
||||
chan->input_count++;
|
||||
chan->inputs[i].input.type = V4L2_INPUT_TYPE_CAMERA;
|
||||
|
@ -1589,10 +1587,10 @@ vpif_capture_get_pdata(struct platform_device *pdev)
|
|||
pdata->asd[i] = v4l2_async_notifier_add_fwnode_subdev(
|
||||
&vpif_obj.notifier, of_fwnode_handle(rem),
|
||||
sizeof(struct v4l2_async_subdev));
|
||||
if (IS_ERR(pdata->asd[i])) {
|
||||
of_node_put(rem);
|
||||
if (IS_ERR(pdata->asd[i]))
|
||||
goto err_cleanup;
|
||||
}
|
||||
|
||||
of_node_put(rem);
|
||||
}
|
||||
|
||||
done:
|
||||
|
@ -1604,6 +1602,7 @@ vpif_capture_get_pdata(struct platform_device *pdev)
|
|||
return pdata;
|
||||
|
||||
err_cleanup:
|
||||
of_node_put(rem);
|
||||
of_node_put(endpoint);
|
||||
v4l2_async_notifier_cleanup(&vpif_obj.notifier);
|
||||
|
||||
|
|
|
@ -486,9 +486,9 @@ static int camss_of_parse_ports(struct camss *camss)
|
|||
asd = v4l2_async_notifier_add_fwnode_subdev(
|
||||
&camss->notifier, of_fwnode_handle(remote),
|
||||
sizeof(*csd));
|
||||
of_node_put(remote);
|
||||
if (IS_ERR(asd)) {
|
||||
ret = PTR_ERR(asd);
|
||||
of_node_put(remote);
|
||||
goto err_cleanup;
|
||||
}
|
||||
|
||||
|
|
|
@ -385,9 +385,9 @@ static int xvip_graph_parse_one(struct xvip_composite_device *xdev,
|
|||
asd = v4l2_async_notifier_add_fwnode_subdev(
|
||||
&xdev->notifier, remote,
|
||||
sizeof(struct xvip_graph_entity));
|
||||
fwnode_handle_put(remote);
|
||||
if (IS_ERR(asd)) {
|
||||
ret = PTR_ERR(asd);
|
||||
fwnode_handle_put(remote);
|
||||
goto err_notifier_cleanup;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -775,23 +775,17 @@ static int v4l2_fwnode_reference_parse(struct device *dev,
|
|||
asd = v4l2_async_notifier_add_fwnode_subdev(notifier,
|
||||
args.fwnode,
|
||||
sizeof(*asd));
|
||||
fwnode_handle_put(args.fwnode);
|
||||
if (IS_ERR(asd)) {
|
||||
ret = PTR_ERR(asd);
|
||||
/* not an error if asd already exists */
|
||||
if (ret == -EEXIST) {
|
||||
fwnode_handle_put(args.fwnode);
|
||||
if (PTR_ERR(asd) == -EEXIST)
|
||||
continue;
|
||||
}
|
||||
|
||||
goto error;
|
||||
return PTR_ERR(asd);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
error:
|
||||
fwnode_handle_put(args.fwnode);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1081,23 +1075,18 @@ v4l2_fwnode_reference_parse_int_props(struct device *dev,
|
|||
|
||||
asd = v4l2_async_notifier_add_fwnode_subdev(notifier, fwnode,
|
||||
sizeof(*asd));
|
||||
fwnode_handle_put(fwnode);
|
||||
if (IS_ERR(asd)) {
|
||||
ret = PTR_ERR(asd);
|
||||
/* not an error if asd already exists */
|
||||
if (ret == -EEXIST) {
|
||||
fwnode_handle_put(fwnode);
|
||||
if (ret == -EEXIST)
|
||||
continue;
|
||||
}
|
||||
|
||||
goto error;
|
||||
return PTR_ERR(asd);
|
||||
}
|
||||
}
|
||||
|
||||
return !fwnode || PTR_ERR(fwnode) == -ENOENT ? 0 : PTR_ERR(fwnode);
|
||||
|
||||
error:
|
||||
fwnode_handle_put(fwnode);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int v4l2_async_notifier_parse_fwnode_sensor_common(struct device *dev,
|
||||
|
|
|
@ -172,8 +172,9 @@ int v4l2_async_notifier_add_subdev(struct v4l2_async_notifier *notifier,
|
|||
* the driver's async sub-device struct, i.e. both
|
||||
* begin at the same memory address.
|
||||
*
|
||||
* Allocate a fwnode-matched asd of size asd_struct_size, and add it
|
||||
* to the notifiers @asd_list.
|
||||
* Allocate a fwnode-matched asd of size asd_struct_size, and add it to the
|
||||
* notifiers @asd_list. The function also gets a reference of the fwnode which
|
||||
* is released later at notifier cleanup time.
|
||||
*/
|
||||
struct v4l2_async_subdev *
|
||||
v4l2_async_notifier_add_fwnode_subdev(struct v4l2_async_notifier *notifier,
|
||||
|
|
Loading…
Reference in New Issue