media: atmel: Use v4l2_async_notifier_add_fwnode_remote_subdev

The use of v4l2_async_notifier_add_subdev will be discouraged.
Drivers are instead encouraged to use a helper such as
v4l2_async_notifier_add_fwnode_remote_subdev.

This fixes a misuse of the API, as v4l2_async_notifier_add_subdev
should get a kmalloc'ed struct v4l2_async_subdev,
removing some boilerplate code while at it.

Signed-off-by: Ezequiel Garcia <ezequiel@collabora.com>
Reviewed-by: Jacopo Mondi <jacopo+renesas@jmondi.org>
Reviewed-by: Helen Koike <helen.koike@collabora.com>
Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
This commit is contained in:
Ezequiel Garcia 2021-01-18 02:52:46 +01:00 committed by Mauro Carvalho Chehab
parent c1cf3d896d
commit d6701f13bd
3 changed files with 29 additions and 62 deletions

View File

@ -41,6 +41,7 @@ struct isc_buffer {
struct isc_subdev_entity {
struct v4l2_subdev *sd;
struct v4l2_async_subdev *asd;
struct device_node *epn;
struct v4l2_async_notifier notifier;
u32 pfe_cfg0;

View File

@ -70,7 +70,6 @@ struct frame_buffer {
struct isi_graph_entity {
struct device_node *node;
struct v4l2_async_subdev asd;
struct v4l2_subdev *subdev;
};
@ -1136,45 +1135,26 @@ static const struct v4l2_async_notifier_operations isi_graph_notify_ops = {
.complete = isi_graph_notify_complete,
};
static int isi_graph_parse(struct atmel_isi *isi, struct device_node *node)
static int isi_graph_init(struct atmel_isi *isi)
{
struct device_node *ep = NULL;
struct device_node *remote;
struct v4l2_async_subdev *asd;
struct device_node *ep;
int ret;
ep = of_graph_get_next_endpoint(node, ep);
ep = of_graph_get_next_endpoint(isi->dev->of_node, NULL);
if (!ep)
return -EINVAL;
remote = of_graph_get_remote_port_parent(ep);
of_node_put(ep);
if (!remote)
return -EINVAL;
/* Remote node to connect */
isi->entity.node = remote;
isi->entity.asd.match_type = V4L2_ASYNC_MATCH_FWNODE;
isi->entity.asd.match.fwnode = of_fwnode_handle(remote);
return 0;
}
static int isi_graph_init(struct atmel_isi *isi)
{
int ret;
/* Parse the graph to extract a list of subdevice DT nodes. */
ret = isi_graph_parse(isi, isi->dev->of_node);
if (ret < 0) {
dev_err(isi->dev, "Graph parsing failed\n");
return ret;
}
v4l2_async_notifier_init(&isi->notifier);
ret = v4l2_async_notifier_add_subdev(&isi->notifier, &isi->entity.asd);
if (ret) {
of_node_put(isi->entity.node);
return ret;
}
asd = v4l2_async_notifier_add_fwnode_remote_subdev(
&isi->notifier,
of_fwnode_handle(ep),
sizeof(*asd));
of_node_put(ep);
if (IS_ERR(asd))
return PTR_ERR(asd);
isi->notifier.ops = &isi_graph_notify_ops;

View File

@ -57,7 +57,7 @@
static int isc_parse_dt(struct device *dev, struct isc_device *isc)
{
struct device_node *np = dev->of_node;
struct device_node *epn = NULL, *rem;
struct device_node *epn = NULL;
struct isc_subdev_entity *subdev_entity;
unsigned int flags;
int ret;
@ -71,17 +71,9 @@ static int isc_parse_dt(struct device *dev, struct isc_device *isc)
if (!epn)
return 0;
rem = of_graph_get_remote_port_parent(epn);
if (!rem) {
dev_notice(dev, "Remote device at %pOF not found\n",
epn);
continue;
}
ret = v4l2_fwnode_endpoint_parse(of_fwnode_handle(epn),
&v4l2_epn);
if (ret) {
of_node_put(rem);
ret = -EINVAL;
dev_err(dev, "Could not parse the endpoint\n");
break;
@ -90,21 +82,10 @@ static int isc_parse_dt(struct device *dev, struct isc_device *isc)
subdev_entity = devm_kzalloc(dev, sizeof(*subdev_entity),
GFP_KERNEL);
if (!subdev_entity) {
of_node_put(rem);
ret = -ENOMEM;
break;
}
/* asd will be freed by the subsystem once it's added to the
* notifier list
*/
subdev_entity->asd = kzalloc(sizeof(*subdev_entity->asd),
GFP_KERNEL);
if (!subdev_entity->asd) {
of_node_put(rem);
ret = -ENOMEM;
break;
}
subdev_entity->epn = epn;
flags = v4l2_epn.bus.parallel.flags;
@ -121,12 +102,10 @@ static int isc_parse_dt(struct device *dev, struct isc_device *isc)
subdev_entity->pfe_cfg0 |= ISC_PFE_CFG0_CCIR_CRC |
ISC_PFE_CFG0_CCIR656;
subdev_entity->asd->match_type = V4L2_ASYNC_MATCH_FWNODE;
subdev_entity->asd->match.fwnode = of_fwnode_handle(rem);
list_add_tail(&subdev_entity->list, &isc->subdev_entities);
}
of_node_put(epn);
return ret;
}
@ -228,13 +207,20 @@ static int atmel_isc_probe(struct platform_device *pdev)
}
list_for_each_entry(subdev_entity, &isc->subdev_entities, list) {
struct v4l2_async_subdev *asd;
v4l2_async_notifier_init(&subdev_entity->notifier);
ret = v4l2_async_notifier_add_subdev(&subdev_entity->notifier,
subdev_entity->asd);
if (ret) {
fwnode_handle_put(subdev_entity->asd->match.fwnode);
kfree(subdev_entity->asd);
asd = v4l2_async_notifier_add_fwnode_remote_subdev(
&subdev_entity->notifier,
of_fwnode_handle(subdev_entity->epn),
sizeof(*asd));
of_node_put(subdev_entity->epn);
subdev_entity->epn = NULL;
if (IS_ERR(asd)) {
ret = PTR_ERR(asd);
goto cleanup_subdev;
}