[media] exynos4-is: Add locking at fimc(-lite) subdev unregistered handler
authorSylwester Nawrocki <s.nawrocki@samsung.com>
Fri, 31 May 2013 14:37:25 +0000 (11:37 -0300)
committerMauro Carvalho Chehab <mchehab@redhat.com>
Thu, 13 Jun 2013 01:01:53 +0000 (22:01 -0300)
Protect the fimc/fimc-lite video nodes unregistration with their video
lock. This prevents a kernel crash when e.g. udev opens a video node
right after the driver registers it and then the driver tries to
unregister it and defers its probing. Using video_is_unregistered()
together with the video mutex allows safe unregistration of the video
nodes at any time.

Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
drivers/media/platform/exynos4-is/fimc-capture.c
drivers/media/platform/exynos4-is/fimc-lite.c

index 33c6a2f0ad74eedafd681df05baf1eba665088e9..1578aa4e4bb55eb7ffcb3c502845906165dee97a 100644 (file)
@@ -1855,6 +1855,8 @@ static void fimc_capture_subdev_unregistered(struct v4l2_subdev *sd)
        if (fimc == NULL)
                return;
 
+       mutex_lock(&fimc->lock);
+
        fimc_unregister_m2m_device(fimc);
        vdev = &fimc->vid_cap.ve.vdev;
 
@@ -1866,6 +1868,8 @@ static void fimc_capture_subdev_unregistered(struct v4l2_subdev *sd)
        }
        kfree(fimc->vid_cap.ctx);
        fimc->vid_cap.ctx = NULL;
+
+       mutex_unlock(&fimc->lock);
 }
 
 static const struct v4l2_subdev_internal_ops fimc_capture_sd_internal_ops = {
index 24e2a0f8797a560dfaaadc4722503e744c990136..3f76f8abc4b31ad2f3997f58d0d37781566c4d91 100644 (file)
@@ -1300,11 +1300,15 @@ static void fimc_lite_subdev_unregistered(struct v4l2_subdev *sd)
        if (fimc == NULL)
                return;
 
+       mutex_lock(&fimc->lock);
+
        if (video_is_registered(&fimc->ve.vdev)) {
                video_unregister_device(&fimc->ve.vdev);
                media_entity_cleanup(&fimc->ve.vdev.entity);
                fimc->ve.pipe = NULL;
        }
+
+       mutex_unlock(&fimc->lock);
 }
 
 static const struct v4l2_subdev_internal_ops fimc_lite_subdev_internal_ops = {