Commit 4babf057 authored by Dafna Hirschfeld's avatar Dafna Hirschfeld Committed by Mauro Carvalho Chehab

media: vimc: allocate vimc_device dynamically

In future patch, the release of the device will move
to the release callback of v4l2_device. Therefore the
device will be released only when the last fh will be
closed. Dynamic allocation will then be needed since
when the device is unbounded and then bounded again,
it might be that the probe callback will run before
the release of the last device is finished. In that
case both operations will run on the same memory
concurrently and cause memory corruption.
This patch also removes the pdev field of
vimc_device since it is not needed anymore.
Signed-off-by: default avatarDafna Hirschfeld <dafna.hirschfeld@collabora.com>
Signed-off-by: default avatarHans Verkuil <hverkuil-cisco@xs4all.nl>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab+huawei@kernel.org>
parent 2362f53d
...@@ -106,14 +106,12 @@ struct vimc_ent_device { ...@@ -106,14 +106,12 @@ struct vimc_ent_device {
/** /**
* struct vimc_device - main device for vimc driver * struct vimc_device - main device for vimc driver
* *
* @pdev pointer to the platform device
* @pipe_cfg pointer to the vimc pipeline configuration structure * @pipe_cfg pointer to the vimc pipeline configuration structure
* @ent_devs array of vimc_ent_device pointers * @ent_devs array of vimc_ent_device pointers
* @mdev the associated media_device parent * @mdev the associated media_device parent
* @v4l2_dev Internal v4l2 parent device * @v4l2_dev Internal v4l2 parent device
*/ */
struct vimc_device { struct vimc_device {
struct platform_device pdev;
const struct vimc_pipeline_config *pipe_cfg; const struct vimc_pipeline_config *pipe_cfg;
struct vimc_ent_device **ent_devs; struct vimc_ent_device **ent_devs;
struct media_device mdev; struct media_device mdev;
......
...@@ -252,16 +252,21 @@ static void vimc_unregister(struct vimc_device *vimc) ...@@ -252,16 +252,21 @@ static void vimc_unregister(struct vimc_device *vimc)
media_device_cleanup(&vimc->mdev); media_device_cleanup(&vimc->mdev);
v4l2_device_unregister(&vimc->v4l2_dev); v4l2_device_unregister(&vimc->v4l2_dev);
kfree(vimc->ent_devs); kfree(vimc->ent_devs);
kfree(vimc);
} }
static int vimc_probe(struct platform_device *pdev) static int vimc_probe(struct platform_device *pdev)
{ {
struct vimc_device *vimc = container_of(pdev, struct vimc_device, pdev); struct vimc_device *vimc;
int ret; int ret;
dev_dbg(&pdev->dev, "probe"); dev_dbg(&pdev->dev, "probe");
memset(&vimc->mdev, 0, sizeof(vimc->mdev)); vimc = kzalloc(sizeof(*vimc), GFP_KERNEL);
if (!vimc)
return -ENOMEM;
vimc->pipe_cfg = &pipe_cfg;
/* Link the media device within the v4l2_device */ /* Link the media device within the v4l2_device */
vimc->v4l2_dev.mdev = &vimc->mdev; vimc->v4l2_dev.mdev = &vimc->mdev;
...@@ -277,15 +282,17 @@ static int vimc_probe(struct platform_device *pdev) ...@@ -277,15 +282,17 @@ static int vimc_probe(struct platform_device *pdev)
ret = vimc_register_devices(vimc); ret = vimc_register_devices(vimc);
if (ret) { if (ret) {
media_device_cleanup(&vimc->mdev); media_device_cleanup(&vimc->mdev);
kfree(vimc);
return ret; return ret;
} }
platform_set_drvdata(pdev, vimc);
return 0; return 0;
} }
static int vimc_remove(struct platform_device *pdev) static int vimc_remove(struct platform_device *pdev)
{ {
struct vimc_device *vimc = container_of(pdev, struct vimc_device, pdev); struct vimc_device *vimc = platform_get_drvdata(pdev);
dev_dbg(&pdev->dev, "remove"); dev_dbg(&pdev->dev, "remove");
...@@ -299,12 +306,9 @@ static void vimc_dev_release(struct device *dev) ...@@ -299,12 +306,9 @@ static void vimc_dev_release(struct device *dev)
{ {
} }
static struct vimc_device vimc_dev = { static struct platform_device vimc_pdev = {
.pipe_cfg = &pipe_cfg, .name = VIMC_PDEV_NAME,
.pdev = { .dev.release = vimc_dev_release,
.name = VIMC_PDEV_NAME,
.dev.release = vimc_dev_release,
}
}; };
static struct platform_driver vimc_pdrv = { static struct platform_driver vimc_pdrv = {
...@@ -319,16 +323,16 @@ static int __init vimc_init(void) ...@@ -319,16 +323,16 @@ static int __init vimc_init(void)
{ {
int ret; int ret;
ret = platform_device_register(&vimc_dev.pdev); ret = platform_device_register(&vimc_pdev);
if (ret) { if (ret) {
dev_err(&vimc_dev.pdev.dev, dev_err(&vimc_pdev.dev,
"platform device registration failed (err=%d)\n", ret); "platform device registration failed (err=%d)\n", ret);
return ret; return ret;
} }
ret = platform_driver_register(&vimc_pdrv); ret = platform_driver_register(&vimc_pdrv);
if (ret) { if (ret) {
dev_err(&vimc_dev.pdev.dev, dev_err(&vimc_pdev.dev,
"platform driver registration failed (err=%d)\n", ret); "platform driver registration failed (err=%d)\n", ret);
platform_driver_unregister(&vimc_pdrv); platform_driver_unregister(&vimc_pdrv);
return ret; return ret;
...@@ -341,7 +345,7 @@ static void __exit vimc_exit(void) ...@@ -341,7 +345,7 @@ static void __exit vimc_exit(void)
{ {
platform_driver_unregister(&vimc_pdrv); platform_driver_unregister(&vimc_pdrv);
platform_device_unregister(&vimc_dev.pdev); platform_device_unregister(&vimc_pdev);
} }
module_init(vimc_init); module_init(vimc_init);
......
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