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>
This commit is contained in:
Родитель
4ce4646c23
Коммит
7a040cf303
|
@ -160,24 +160,6 @@ err_rm_links:
|
||||||
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)
|
||||||
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)
|
||||||
/* 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 @@ err_mdev_unregister:
|
||||||
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);
|
||||||
|
|
Загрузка…
Ссылка в новой задаче