Commit 7a040cf3 authored by Dafna Hirschfeld's avatar Dafna Hirschfeld Committed by Mauro Carvalho Chehab

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: 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 4ce4646c
...@@ -160,24 +160,6 @@ static int vimc_create_links(struct vimc_device *vimc) ...@@ -160,24 +160,6 @@ static int vimc_create_links(struct vimc_device *vimc)
return ret; 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) static void vimc_release_subdevs(struct vimc_device *vimc)
{ {
unsigned int i; unsigned int i;
...@@ -196,6 +178,26 @@ static void vimc_unregister_subdevs(struct vimc_device *vimc) ...@@ -196,6 +178,26 @@ static void vimc_unregister_subdevs(struct vimc_device *vimc)
vimc->pipe_cfg->ents[i].unregister(vimc->ent_devs[i]); 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) static void vimc_v4l2_dev_release(struct v4l2_device *v4l2_dev)
{ {
struct vimc_device *vimc = struct vimc_device *vimc =
...@@ -229,8 +231,7 @@ static int vimc_register_devices(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 */ /* Invoke entity config hooks to initialize and register subdevs */
ret = vimc_add_subdevs(vimc); ret = vimc_add_subdevs(vimc);
if (ret) if (ret)
/* remove sundevs that got added */ goto err_free_ent_devs;
goto err_rm_subdevs;
/* Initialize links */ /* Initialize links */
ret = vimc_create_links(vimc); ret = vimc_create_links(vimc);
...@@ -261,6 +262,7 @@ static int vimc_register_devices(struct vimc_device *vimc) ...@@ -261,6 +262,7 @@ static int vimc_register_devices(struct vimc_device *vimc)
err_rm_subdevs: err_rm_subdevs:
vimc_unregister_subdevs(vimc); vimc_unregister_subdevs(vimc);
vimc_release_subdevs(vimc); vimc_release_subdevs(vimc);
err_free_ent_devs:
kfree(vimc->ent_devs); kfree(vimc->ent_devs);
err_v4l2_unregister: err_v4l2_unregister:
v4l2_device_unregister(&vimc->v4l2_dev); v4l2_device_unregister(&vimc->v4l2_dev);
......
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