Commit 0783525f authored by Hans Verkuil's avatar Hans Verkuil Committed by Mauro Carvalho Chehab

media: vicodec: correctly support unbinding of the driver

Unbinding the driver while streaming caused the driver to hang.

The cause of this was failing to use the v4l2_device release
function and the use of devm_kmalloc for the state structure.
Signed-off-by: default avatarHans Verkuil <hverkuil-cisco@xs4all.nl>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab+samsung@kernel.org>
parent bfe81950
...@@ -2013,18 +2013,31 @@ static int register_instance(struct vicodec_dev *dev, ...@@ -2013,18 +2013,31 @@ static int register_instance(struct vicodec_dev *dev,
return 0; return 0;
} }
static void vicodec_v4l2_dev_release(struct v4l2_device *v4l2_dev)
{
struct vicodec_dev *dev = container_of(v4l2_dev, struct vicodec_dev, v4l2_dev);
v4l2_device_unregister(&dev->v4l2_dev);
v4l2_m2m_release(dev->stateful_enc.m2m_dev);
v4l2_m2m_release(dev->stateful_dec.m2m_dev);
v4l2_m2m_release(dev->stateless_dec.m2m_dev);
kfree(dev);
}
static int vicodec_probe(struct platform_device *pdev) static int vicodec_probe(struct platform_device *pdev)
{ {
struct vicodec_dev *dev; struct vicodec_dev *dev;
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 free_dev;
dev->v4l2_dev.release = vicodec_v4l2_dev_release;
#ifdef CONFIG_MEDIA_CONTROLLER #ifdef CONFIG_MEDIA_CONTROLLER
dev->mdev.dev = &pdev->dev; dev->mdev.dev = &pdev->dev;
...@@ -2102,6 +2115,8 @@ static int vicodec_probe(struct platform_device *pdev) ...@@ -2102,6 +2115,8 @@ static int vicodec_probe(struct platform_device *pdev)
v4l2_m2m_release(dev->stateful_enc.m2m_dev); v4l2_m2m_release(dev->stateful_enc.m2m_dev);
unreg_dev: unreg_dev:
v4l2_device_unregister(&dev->v4l2_dev); v4l2_device_unregister(&dev->v4l2_dev);
free_dev:
kfree(dev);
return ret; return ret;
} }
...@@ -2120,12 +2135,10 @@ static int vicodec_remove(struct platform_device *pdev) ...@@ -2120,12 +2135,10 @@ static int vicodec_remove(struct platform_device *pdev)
media_device_cleanup(&dev->mdev); media_device_cleanup(&dev->mdev);
#endif #endif
v4l2_m2m_release(dev->stateful_enc.m2m_dev);
v4l2_m2m_release(dev->stateful_dec.m2m_dev);
video_unregister_device(&dev->stateful_enc.vfd); video_unregister_device(&dev->stateful_enc.vfd);
video_unregister_device(&dev->stateful_dec.vfd); video_unregister_device(&dev->stateful_dec.vfd);
video_unregister_device(&dev->stateless_dec.vfd); video_unregister_device(&dev->stateless_dec.vfd);
v4l2_device_unregister(&dev->v4l2_dev); v4l2_device_put(&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