media: imx: queue subdev events to reachable video devices
authorSteve Longerbeam <slongerbeam@gmail.com>
Tue, 15 Jan 2019 19:15:46 +0000 (17:15 -0200)
committerMauro Carvalho Chehab <mchehab+samsung@kernel.org>
Mon, 21 Jan 2019 18:43:41 +0000 (16:43 -0200)
In order to receive events generated by subdevices on the video capture
nodes, those events need to be forwarded to the subdevice's list of
reachable video capture devices.

Note this will queue the event to a video device even if there is
no actual _enabled_ media path from the sub-device to the video device.
So a future improvement is to skip the video device if there is no enabled
path to it from the sub-device. The entity->pipe pointer can't be
used for this check because in imx-media a sub-device can be a
member to more than one streaming pipeline at a time.

Signed-off-by: Steve Longerbeam <slongerbeam@gmail.com>
Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
drivers/staging/media/imx/imx-media-dev.c

index 4b344a4..25e9165 100644 (file)
@@ -442,6 +442,29 @@ static const struct media_device_ops imx_media_md_ops = {
        .link_notify = imx_media_link_notify,
 };
 
+static void imx_media_notify(struct v4l2_subdev *sd,
+                            unsigned int notification,
+                            void *arg)
+{
+       struct media_entity *entity = &sd->entity;
+       int i;
+
+       if (notification != V4L2_DEVICE_NOTIFY_EVENT)
+               return;
+
+       for (i = 0; i < entity->num_pads; i++) {
+               struct media_pad *pad = &entity->pads[i];
+               struct imx_media_pad_vdev *pad_vdev;
+               struct list_head *pad_vdev_list;
+
+               pad_vdev_list = to_pad_vdev_list(sd, pad->index);
+               if (!pad_vdev_list)
+                       continue;
+               list_for_each_entry(pad_vdev, pad_vdev_list, list)
+                       v4l2_event_queue(pad_vdev->vdev->vfd, arg);
+       }
+}
+
 static int imx_media_probe(struct platform_device *pdev)
 {
        struct device *dev = &pdev->dev;
@@ -462,6 +485,7 @@ static int imx_media_probe(struct platform_device *pdev)
        mutex_init(&imxmd->mutex);
 
        imxmd->v4l2_dev.mdev = &imxmd->md;
+       imxmd->v4l2_dev.notify = imx_media_notify;
        strscpy(imxmd->v4l2_dev.name, "imx-media",
                sizeof(imxmd->v4l2_dev.name));