struct isi_graph_entity {
        struct device_node *node;
 
-       struct v4l2_async_subdev asd;
        struct v4l2_subdev *subdev;
 };
 
        .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;
 
 
 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;
                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;
                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;
 
                        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;
 }
 
        }
 
        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;
                }