struct media_pad *srcpad)
 {
        struct media_entity *entity = srcpad->entity;
-       struct imx_media_pad *imxpad;
+       struct imx_media_pad_vdev *pad_vdev;
+       struct list_head *pad_vdev_list;
        struct media_link *link;
        struct v4l2_subdev *sd;
-       int i, vdev_idx, ret;
+       int i, ret;
 
        /* skip this entity if not a v4l2_subdev */
        if (!is_media_entity_v4l2_subdev(entity))
 
        sd = media_entity_to_v4l2_subdev(entity);
 
-       imxpad = to_imx_media_pad(sd, srcpad->index);
-       if (!imxpad) {
+       pad_vdev_list = to_pad_vdev_list(sd, srcpad->index);
+       if (!pad_vdev_list) {
                v4l2_warn(&imxmd->v4l2_dev, "%s:%u has no vdev list!\n",
                          entity->name, srcpad->index);
                /*
                return 0;
        }
 
-       vdev_idx = imxpad->num_vdevs;
-
        /* just return if we've been here before */
-       for (i = 0; i < vdev_idx; i++)
-               if (vdev == imxpad->vdev[i])
+       list_for_each_entry(pad_vdev, pad_vdev_list, list) {
+               if (pad_vdev->vdev == vdev)
                        return 0;
-
-       if (vdev_idx >= IMX_MEDIA_MAX_VDEVS) {
-               dev_err(imxmd->md.dev, "can't add %s to pad %s:%u\n",
-                       vdev->vfd->entity.name, entity->name, srcpad->index);
-               return -ENOSPC;
        }
 
        dev_dbg(imxmd->md.dev, "adding %s to pad %s:%u\n",
                vdev->vfd->entity.name, entity->name, srcpad->index);
-       imxpad->vdev[vdev_idx] = vdev;
-       imxpad->num_vdevs++;
+
+       pad_vdev = devm_kzalloc(imxmd->md.dev, sizeof(*pad_vdev), GFP_KERNEL);
+       if (!pad_vdev)
+               return -ENOMEM;
+
+       /* attach this vdev to this pad */
+       pad_vdev->vdev = vdev;
+       list_add_tail(&pad_vdev->list, pad_vdev_list);
 
        /* move upstream from this entity's sink pads */
        for (i = 0; i < entity->num_pads; i++) {
        return 0;
 }
 
+/*
+ * For every subdevice, allocate an array of list_head's, one list_head
+ * for each pad, to hold the list of video devices reachable from that
+ * pad.
+ */
 static int imx_media_alloc_pad_vdev_lists(struct imx_media_dev *imxmd)
 {
-       struct imx_media_pad *imxpads;
+       struct list_head *vdev_lists;
        struct media_entity *entity;
        struct v4l2_subdev *sd;
+       int i;
 
        list_for_each_entry(sd, &imxmd->v4l2_dev.subdevs, list) {
                entity = &sd->entity;
-               imxpads = devm_kzalloc(imxmd->md.dev,
-                                      entity->num_pads * sizeof(*imxpads),
-                                      GFP_KERNEL);
-               if (!imxpads)
+               vdev_lists = devm_kzalloc(
+                       imxmd->md.dev,
+                       entity->num_pads * sizeof(*vdev_lists),
+                       GFP_KERNEL);
+               if (!vdev_lists)
                        return -ENOMEM;
 
-               /* attach imxpads to the subdev's host private pointer */
-               sd->host_priv = imxpads;
+               /* attach to the subdev's host private pointer */
+               sd->host_priv = vdev_lists;
+
+               for (i = 0; i < entity->num_pads; i++)
+                       INIT_LIST_HEAD(to_pad_vdev_list(sd, i));
        }
 
        return 0;
 {
        struct imx_media_video_dev *vdev;
        struct media_link *link;
-       int i, ret;
+       int ret;
 
        ret = imx_media_alloc_pad_vdev_lists(imxmd);
        if (ret)
                return ret;
 
-       for (i = 0; i < imxmd->num_vdevs; i++) {
-               vdev = imxmd->vdev[i];
+       list_for_each_entry(vdev, &imxmd->vdev_list, list) {
                link = list_first_entry(&vdev->vfd->entity.links,
                                        struct media_link, list);
                ret = imx_media_add_vdev_to_pad(imxmd, vdev, link->source);
                                 unsigned int notification)
 {
        struct media_entity *source = link->source->entity;
-       struct imx_media_pad *imxpad;
+       struct imx_media_pad_vdev *pad_vdev;
+       struct list_head *pad_vdev_list;
        struct imx_media_dev *imxmd;
        struct video_device *vfd;
        struct v4l2_subdev *sd;
-       int i, pad_idx, ret;
+       int pad_idx, ret;
 
        ret = v4l2_pipeline_link_notify(link, flags, notification);
        if (ret)
 
        imxmd = dev_get_drvdata(sd->v4l2_dev->dev);
 
-       imxpad = to_imx_media_pad(sd, pad_idx);
-       if (!imxpad) {
+       pad_vdev_list = to_pad_vdev_list(sd, pad_idx);
+       if (!pad_vdev_list) {
                /* shouldn't happen, but no reason to fail link setup */
                return 0;
        }
         */
        if (notification == MEDIA_DEV_NOTIFY_PRE_LINK_CH &&
            !(flags & MEDIA_LNK_FL_ENABLED)) {
-               for (i = 0; i < imxpad->num_vdevs; i++) {
-                       vfd = imxpad->vdev[i]->vfd;
+               list_for_each_entry(pad_vdev, pad_vdev_list, list) {
+                       vfd = pad_vdev->vdev->vfd;
                        dev_dbg(imxmd->md.dev,
                                "reset controls for %s\n",
                                vfd->entity.name);
                }
        } else if (notification == MEDIA_DEV_NOTIFY_POST_LINK_CH &&
                   (link->flags & MEDIA_LNK_FL_ENABLED)) {
-               for (i = 0; i < imxpad->num_vdevs; i++) {
-                       vfd = imxpad->vdev[i]->vfd;
+               list_for_each_entry(pad_vdev, pad_vdev_list, list) {
+                       vfd = pad_vdev->vdev->vfd;
                        dev_dbg(imxmd->md.dev,
                                "refresh controls for %s\n",
                                vfd->entity.name);
        dev_set_drvdata(imxmd->v4l2_dev.dev, imxmd);
 
        INIT_LIST_HEAD(&imxmd->asd_list);
+       INIT_LIST_HEAD(&imxmd->vdev_list);
 
        ret = imx_media_add_of_subdevs(imxmd, node);
        if (ret) {
 
 #include <media/videobuf2-dma-contig.h>
 #include <video/imx-ipu-v3.h>
 
-/* max video devices */
-#define IMX_MEDIA_MAX_VDEVS          8
-
 /*
  * Pad definitions for the subdevs with multiple source or
  * sink pads
        /* the user format */
        struct v4l2_format fmt;
        const struct imx_media_pixfmt *cc;
+
+       /* links this vdev to master list */
+       struct list_head list;
 };
 
 static inline struct imx_media_buffer *to_imx_media_vb(struct vb2_buffer *vb)
        return container_of(vbuf, struct imx_media_buffer, vbuf);
 }
 
-/* to support control inheritance to video devices */
-struct imx_media_pad {
-       /*
-        * list of video devices that can be reached from this pad,
-        * list is only valid for source pads.
-        */
-       struct imx_media_video_dev *vdev[IMX_MEDIA_MAX_VDEVS];
-       int num_vdevs;
-};
-
-static inline struct imx_media_pad *
-to_imx_media_pad(struct v4l2_subdev *sd, int pad_index)
+/*
+ * to support control inheritance to video devices, this
+ * retrieves a pad's list_head of video devices that can
+ * be reached from the pad. Note that only the lists in
+ * source pads get populated, sink pads have empty lists.
+ */
+static inline struct list_head *
+to_pad_vdev_list(struct v4l2_subdev *sd, int pad_index)
 {
-       struct imx_media_pad *imxpads = sd->host_priv;
+       struct list_head *vdev_list = sd->host_priv;
 
-       return imxpads ? &imxpads[pad_index] : NULL;
+       return vdev_list ? &vdev_list[pad_index] : NULL;
 }
 
+/* an entry in a pad's video device list */
+struct imx_media_pad_vdev {
+       struct imx_media_video_dev *vdev;
+       struct list_head list;
+};
+
 struct imx_media_internal_sd_platformdata {
        char sd_name[V4L2_SUBDEV_NAME_SIZE];
        u32 grp_id;
        struct mutex mutex; /* protect elements below */
 
        /* master video device list */
-       struct imx_media_video_dev *vdev[IMX_MEDIA_MAX_VDEVS];
-       int num_vdevs;
+       struct list_head vdev_list;
 
        /* IPUs this media driver control, valid after subdevs bound */
        struct ipu_soc *ipu[2];