@@ -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;
@@ -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)
-{
- struct device_node *ep = NULL;
- struct device_node *remote;
-
- ep = of_graph_get_next_endpoint(node, ep);
- 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)
{
+ struct v4l2_async_subdev *asd;
+ struct device_node *ep;
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;
- }
+ ep = of_graph_get_next_endpoint(isi->dev->of_node, NULL);
+ if (!ep)
+ return -EINVAL;
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;
@@ -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;
}