static const struct internal_subdev {
        const struct internal_subdev_id *id;
        struct internal_pad pad[IMX_MEDIA_MAX_PADS];
-       int num_sink_pads;
-       int num_src_pads;
 } int_subdev[num_isd] = {
        [isd_csi0] = {
                .id = &isd_id[isd_csi0],
-               .num_sink_pads = CSI_NUM_SINK_PADS,
-               .num_src_pads = CSI_NUM_SRC_PADS,
                .pad[CSI_SRC_PAD_DIRECT] = {
                        .link = {
                                {
 
        [isd_csi1] = {
                .id = &isd_id[isd_csi1],
-               .num_sink_pads = CSI_NUM_SINK_PADS,
-               .num_src_pads = CSI_NUM_SRC_PADS,
                .pad[CSI_SRC_PAD_DIRECT] = {
                        .link = {
                                {
 
        [isd_vdic] = {
                .id = &isd_id[isd_vdic],
-               .num_sink_pads = VDIC_NUM_SINK_PADS,
-               .num_src_pads = VDIC_NUM_SRC_PADS,
                .pad[VDIC_SRC_PAD_DIRECT] = {
                        .link = {
                                {
 
        [isd_ic_prp] = {
                .id = &isd_id[isd_ic_prp],
-               .num_sink_pads = PRP_NUM_SINK_PADS,
-               .num_src_pads = PRP_NUM_SRC_PADS,
                .pad[PRP_SRC_PAD_PRPENC] = {
                        .link = {
                                {
 
        [isd_ic_prpenc] = {
                .id = &isd_id[isd_ic_prpenc],
-               .num_sink_pads = PRPENCVF_NUM_SINK_PADS,
-               .num_src_pads = PRPENCVF_NUM_SRC_PADS,
        },
 
        [isd_ic_prpvf] = {
                .id = &isd_id[isd_ic_prpvf],
-               .num_sink_pads = PRPENCVF_NUM_SINK_PADS,
-               .num_src_pads = PRPENCVF_NUM_SRC_PADS,
        },
 };
 
        if (IS_ERR(imxsd))
                return PTR_ERR(imxsd);
 
-       imxsd->num_sink_pads = isd->num_sink_pads;
-       imxsd->num_src_pads = isd->num_src_pads;
-
        return 0;
 }
 
 
 /*
  * find the remote device node given local endpoint node
  */
-static void of_get_remote(struct device_node *epnode,
+static bool of_get_remote(struct device_node *epnode,
                          struct device_node **remote_node)
 {
        struct device_node *rp, *rpp;
        struct device_node *remote;
+       bool is_csi_port;
 
        rp = of_graph_get_remote_port(epnode);
        rpp = of_graph_get_remote_port_parent(epnode);
                /* the remote is one of the CSI ports */
                remote = rp;
                of_node_put(rpp);
+               is_csi_port = true;
        } else {
                remote = rpp;
                of_node_put(rp);
+               is_csi_port = false;
        }
 
        if (!of_device_is_available(remote)) {
        } else {
                *remote_node = remote;
        }
+
+       return is_csi_port;
 }
 
 static int
                bool is_csi_port)
 {
        struct imx_media_subdev *imxsd;
-       int i, num_pads, ret;
+       int i, num_ports, ret;
 
        if (!of_device_is_available(sd_np)) {
                dev_dbg(imxmd->md.dev, "%s: %s not enabled\n", __func__,
                return ret;
        }
 
-       if (is_csi_port) {
-               /*
-                * the ipu-csi has one sink port and two source ports.
-                * The source ports are not represented in the device tree,
-                * but are described by the internal pads and links later.
-                */
-               num_pads = CSI_NUM_PADS;
-               imxsd->num_sink_pads = CSI_NUM_SINK_PADS;
-       } else if (of_device_is_compatible(sd_np, "fsl,imx6-mipi-csi2")) {
-               num_pads = of_get_port_count(sd_np);
-               /* the mipi csi2 receiver has only one sink port */
-               imxsd->num_sink_pads = 1;
-       } else if (of_device_is_compatible(sd_np, "video-mux")) {
-               num_pads = of_get_port_count(sd_np);
-               /* for the video mux, all but the last port are sinks */
-               imxsd->num_sink_pads = num_pads - 1;
-       } else {
-               num_pads = of_get_port_count(sd_np);
-               if (num_pads != 1) {
-                       /* confused, but no reason to give up here */
-                       dev_warn(imxmd->md.dev,
-                                "%s: unknown device %s with %d ports\n",
-                                __func__, sd_np->name, num_pads);
-                       return 0;
-               }
+       /*
+        * the ipu-csi has one sink port. The source pads are not
+        * represented in the device tree by port nodes, but are
+        * described by the internal pads and links later.
+        */
+       num_ports = is_csi_port ? 1 : of_get_port_count(sd_np);
 
-               /*
-                * we got to this node from this single source port,
-                * there are no sink pads.
-                */
-               imxsd->num_sink_pads = 0;
-       }
-
-       if (imxsd->num_sink_pads >= num_pads)
-               return -EINVAL;
-
-       imxsd->num_src_pads = num_pads - imxsd->num_sink_pads;
-
-       dev_dbg(imxmd->md.dev, "%s: %s has %d pads (%d sink, %d src)\n",
-               __func__, sd_np->name, num_pads,
-               imxsd->num_sink_pads, imxsd->num_src_pads);
-
-       for (i = 0; i < num_pads; i++) {
+       for (i = 0; i < num_ports; i++) {
                struct device_node *epnode = NULL, *port, *remote_np;
 
-               if (is_csi_port)
-                       port = (i < imxsd->num_sink_pads) ? sd_np : NULL;
-               else
-                       port = of_graph_get_port_by_id(sd_np, i);
+               port = is_csi_port ? sd_np : of_graph_get_port_by_id(sd_np, i);
                if (!port)
                        continue;
 
                for_each_child_of_node(port, epnode) {
-                       of_get_remote(epnode, &remote_np);
+                       bool remote_is_csi;
+
+                       remote_is_csi = of_get_remote(epnode, &remote_np);
                        if (!remote_np)
                                continue;
 
-                       if (i < imxsd->num_sink_pads) {
-                               /* follow sink endpoints upstream */
-                               ret = of_parse_subdev(imxmd, remote_np, false);
-                               if (ret)
-                                       break;
-                       }
-
+                       ret = of_parse_subdev(imxmd, remote_np, remote_is_csi);
                        of_node_put(remote_np);
+                       if (ret)
+                               break;
                }
 
                if (port != sd_np)
                        of_node_put(port);
                if (ret) {
-                       of_node_put(remote_np);
                        of_node_put(epnode);
                        break;
                }
 
        CSI_NUM_PADS,
 };
 
-#define CSI_NUM_SINK_PADS 1
-#define CSI_NUM_SRC_PADS  2
-
 /* ipu_vdic */
 enum {
        VDIC_SINK_PAD_DIRECT = 0,
        VDIC_NUM_PADS,
 };
 
-#define VDIC_NUM_SINK_PADS 2
-#define VDIC_NUM_SRC_PADS  1
-
 /* ipu_ic_prp */
 enum {
        PRP_SINK_PAD = 0,
        PRP_NUM_PADS,
 };
 
-#define PRP_NUM_SINK_PADS 1
-#define PRP_NUM_SRC_PADS  2
-
 /* ipu_ic_prpencvf */
 enum {
        PRPENCVF_SINK_PAD = 0,
        PRPENCVF_NUM_PADS,
 };
 
-#define PRPENCVF_NUM_SINK_PADS 1
-#define PRPENCVF_NUM_SRC_PADS  1
-
 /* How long to wait for EOF interrupts in the buffer-capture subdevs */
 #define IMX_MEDIA_EOF_TIMEOUT       1000
 
        struct v4l2_subdev       *sd; /* set when bound */
 
        struct imx_media_pad     pad[IMX_MEDIA_MAX_PADS];
-       int num_sink_pads;
-       int num_src_pads;
 
        /* the platform device if this is an IPU-internal subdev */
        struct platform_device *pdev;