summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDafna Hirschfeld <dafna.hirschfeld@collabora.com>2020-03-28 08:52:51 +0100
committerMauro Carvalho Chehab <mchehab+huawei@kernel.org>2020-04-14 12:01:43 +0200
commit7a040cf303438c567fceb987f10cfd058619f2c9 (patch)
tree48ff67b86070f5369cd2bab73876d4a0a1acdf89
parent4ce4646c23373b20a156b73b398dc04aea14fce8 (diff)
downloadlinux-7a040cf303438c567fceb987f10cfd058619f2c9.tar.gz
linux-7a040cf303438c567fceb987f10cfd058619f2c9.zip
media: vimc: handle error in vimc_add_subdevs
In case the 'add' callback of an entity fails, then all other entities should unregister and released. This should be done inside vimc_add_subdevs so that the function handles its own failure. In order to call vimc_unregister_subdevs and vimc_release_subdevs from vimc_add_subdevs, the order of the function should change. Signed-off-by: Dafna Hirschfeld <dafna.hirschfeld@collabora.com> Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl> Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
-rw-r--r--drivers/media/test_drivers/vimc/vimc-core.c42
1 files changed, 22 insertions, 20 deletions
diff --git a/drivers/media/test_drivers/vimc/vimc-core.c b/drivers/media/test_drivers/vimc/vimc-core.c
index 1f8498837646..dab01cbc31d2 100644
--- a/drivers/media/test_drivers/vimc/vimc-core.c
+++ b/drivers/media/test_drivers/vimc/vimc-core.c
@@ -160,24 +160,6 @@ err_rm_links:
return ret;
}
-static int vimc_add_subdevs(struct vimc_device *vimc)
-{
- unsigned int i;
-
- for (i = 0; i < vimc->pipe_cfg->num_ents; i++) {
- dev_dbg(vimc->mdev.dev, "new entity for %s\n",
- vimc->pipe_cfg->ents[i].name);
- vimc->ent_devs[i] = vimc->pipe_cfg->ents[i].add(vimc,
- vimc->pipe_cfg->ents[i].name);
- if (!vimc->ent_devs[i]) {
- dev_err(vimc->mdev.dev, "add new entity for %s\n",
- vimc->pipe_cfg->ents[i].name);
- return -EINVAL;
- }
- }
- return 0;
-}
-
static void vimc_release_subdevs(struct vimc_device *vimc)
{
unsigned int i;
@@ -196,6 +178,26 @@ static void vimc_unregister_subdevs(struct vimc_device *vimc)
vimc->pipe_cfg->ents[i].unregister(vimc->ent_devs[i]);
}
+static int vimc_add_subdevs(struct vimc_device *vimc)
+{
+ unsigned int i;
+
+ for (i = 0; i < vimc->pipe_cfg->num_ents; i++) {
+ dev_dbg(vimc->mdev.dev, "new entity for %s\n",
+ vimc->pipe_cfg->ents[i].name);
+ vimc->ent_devs[i] = vimc->pipe_cfg->ents[i].add(vimc,
+ vimc->pipe_cfg->ents[i].name);
+ if (!vimc->ent_devs[i]) {
+ dev_err(vimc->mdev.dev, "add new entity for %s\n",
+ vimc->pipe_cfg->ents[i].name);
+ vimc_unregister_subdevs(vimc);
+ vimc_release_subdevs(vimc);
+ return -EINVAL;
+ }
+ }
+ return 0;
+}
+
static void vimc_v4l2_dev_release(struct v4l2_device *v4l2_dev)
{
struct vimc_device *vimc =
@@ -229,8 +231,7 @@ static int vimc_register_devices(struct vimc_device *vimc)
/* Invoke entity config hooks to initialize and register subdevs */
ret = vimc_add_subdevs(vimc);
if (ret)
- /* remove sundevs that got added */
- goto err_rm_subdevs;
+ goto err_free_ent_devs;
/* Initialize links */
ret = vimc_create_links(vimc);
@@ -261,6 +262,7 @@ err_mdev_unregister:
err_rm_subdevs:
vimc_unregister_subdevs(vimc);
vimc_release_subdevs(vimc);
+err_free_ent_devs:
kfree(vimc->ent_devs);
err_v4l2_unregister:
v4l2_device_unregister(&vimc->v4l2_dev);