Commit 9fcd2e9f authored by Hans Verkuil's avatar Hans Verkuil Committed by Greg Kroah-Hartman

media: vim2m: replace devm_kzalloc by kzalloc

[ Upstream commit ea6c7e34 ]

It is not possible to use devm_kzalloc since that memory is
freed immediately when the device instance is unbound.

Various objects like the video device may still be in use
since someone has the device node open, and when that is closed
it expects the memory to be around.

So use kzalloc and release it at the appropriate time.
Signed-off-by: default avatarHans Verkuil <hverkuil-cisco@xs4all.nl>
Reviewed-by: default avatarLaurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab+samsung@kernel.org>
Signed-off-by: default avatarSasha Levin <sashal@kernel.org>
parent 47517a9f
...@@ -1262,6 +1262,15 @@ static int vim2m_release(struct file *file) ...@@ -1262,6 +1262,15 @@ static int vim2m_release(struct file *file)
return 0; return 0;
} }
static void vim2m_device_release(struct video_device *vdev)
{
struct vim2m_dev *dev = container_of(vdev, struct vim2m_dev, vfd);
v4l2_device_unregister(&dev->v4l2_dev);
v4l2_m2m_release(dev->m2m_dev);
kfree(dev);
}
static const struct v4l2_file_operations vim2m_fops = { static const struct v4l2_file_operations vim2m_fops = {
.owner = THIS_MODULE, .owner = THIS_MODULE,
.open = vim2m_open, .open = vim2m_open,
...@@ -1277,7 +1286,7 @@ static const struct video_device vim2m_videodev = { ...@@ -1277,7 +1286,7 @@ static const struct video_device vim2m_videodev = {
.fops = &vim2m_fops, .fops = &vim2m_fops,
.ioctl_ops = &vim2m_ioctl_ops, .ioctl_ops = &vim2m_ioctl_ops,
.minor = -1, .minor = -1,
.release = video_device_release_empty, .release = vim2m_device_release,
.device_caps = V4L2_CAP_VIDEO_M2M | V4L2_CAP_STREAMING, .device_caps = V4L2_CAP_VIDEO_M2M | V4L2_CAP_STREAMING,
}; };
...@@ -1298,13 +1307,13 @@ static int vim2m_probe(struct platform_device *pdev) ...@@ -1298,13 +1307,13 @@ static int vim2m_probe(struct platform_device *pdev)
struct video_device *vfd; struct video_device *vfd;
int ret; int ret;
dev = devm_kzalloc(&pdev->dev, sizeof(*dev), GFP_KERNEL); dev = kzalloc(sizeof(*dev), GFP_KERNEL);
if (!dev) if (!dev)
return -ENOMEM; return -ENOMEM;
ret = v4l2_device_register(&pdev->dev, &dev->v4l2_dev); ret = v4l2_device_register(&pdev->dev, &dev->v4l2_dev);
if (ret) if (ret)
return ret; goto error_free;
atomic_set(&dev->num_inst, 0); atomic_set(&dev->num_inst, 0);
mutex_init(&dev->dev_mutex); mutex_init(&dev->dev_mutex);
...@@ -1317,7 +1326,7 @@ static int vim2m_probe(struct platform_device *pdev) ...@@ -1317,7 +1326,7 @@ static int vim2m_probe(struct platform_device *pdev)
ret = video_register_device(vfd, VFL_TYPE_GRABBER, 0); ret = video_register_device(vfd, VFL_TYPE_GRABBER, 0);
if (ret) { if (ret) {
v4l2_err(&dev->v4l2_dev, "Failed to register video device\n"); v4l2_err(&dev->v4l2_dev, "Failed to register video device\n");
goto unreg_v4l2; goto error_v4l2;
} }
video_set_drvdata(vfd, dev); video_set_drvdata(vfd, dev);
...@@ -1330,7 +1339,7 @@ static int vim2m_probe(struct platform_device *pdev) ...@@ -1330,7 +1339,7 @@ static int vim2m_probe(struct platform_device *pdev)
if (IS_ERR(dev->m2m_dev)) { if (IS_ERR(dev->m2m_dev)) {
v4l2_err(&dev->v4l2_dev, "Failed to init mem2mem device\n"); v4l2_err(&dev->v4l2_dev, "Failed to init mem2mem device\n");
ret = PTR_ERR(dev->m2m_dev); ret = PTR_ERR(dev->m2m_dev);
goto unreg_dev; goto error_dev;
} }
#ifdef CONFIG_MEDIA_CONTROLLER #ifdef CONFIG_MEDIA_CONTROLLER
...@@ -1346,27 +1355,29 @@ static int vim2m_probe(struct platform_device *pdev) ...@@ -1346,27 +1355,29 @@ static int vim2m_probe(struct platform_device *pdev)
MEDIA_ENT_F_PROC_VIDEO_SCALER); MEDIA_ENT_F_PROC_VIDEO_SCALER);
if (ret) { if (ret) {
v4l2_err(&dev->v4l2_dev, "Failed to init mem2mem media controller\n"); v4l2_err(&dev->v4l2_dev, "Failed to init mem2mem media controller\n");
goto unreg_m2m; goto error_m2m;
} }
ret = media_device_register(&dev->mdev); ret = media_device_register(&dev->mdev);
if (ret) { if (ret) {
v4l2_err(&dev->v4l2_dev, "Failed to register mem2mem media device\n"); v4l2_err(&dev->v4l2_dev, "Failed to register mem2mem media device\n");
goto unreg_m2m_mc; goto error_m2m_mc;
} }
#endif #endif
return 0; return 0;
#ifdef CONFIG_MEDIA_CONTROLLER #ifdef CONFIG_MEDIA_CONTROLLER
unreg_m2m_mc: error_m2m_mc:
v4l2_m2m_unregister_media_controller(dev->m2m_dev); v4l2_m2m_unregister_media_controller(dev->m2m_dev);
unreg_m2m: error_m2m:
v4l2_m2m_release(dev->m2m_dev); v4l2_m2m_release(dev->m2m_dev);
#endif #endif
unreg_dev: error_dev:
video_unregister_device(&dev->vfd); video_unregister_device(&dev->vfd);
unreg_v4l2: error_v4l2:
v4l2_device_unregister(&dev->v4l2_dev); v4l2_device_unregister(&dev->v4l2_dev);
error_free:
kfree(dev);
return ret; return ret;
} }
...@@ -1382,9 +1393,7 @@ static int vim2m_remove(struct platform_device *pdev) ...@@ -1382,9 +1393,7 @@ static int vim2m_remove(struct platform_device *pdev)
v4l2_m2m_unregister_media_controller(dev->m2m_dev); v4l2_m2m_unregister_media_controller(dev->m2m_dev);
media_device_cleanup(&dev->mdev); media_device_cleanup(&dev->mdev);
#endif #endif
v4l2_m2m_release(dev->m2m_dev);
video_unregister_device(&dev->vfd); video_unregister_device(&dev->vfd);
v4l2_device_unregister(&dev->v4l2_dev);
return 0; return 0;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment