diff mbox series

[2/5] media: vimc: handle error in vimc_add_subdevs

Message ID 20200328075254.4616-3-dafna.hirschfeld@collabora.com (mailing list archive)
State New, archived
Headers show
Series media: vimc: various fixes | expand

Commit Message

Dafna Hirschfeld March 28, 2020, 7:52 a.m. UTC
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>
---
 drivers/media/platform/vimc/vimc-core.c | 42 +++++++++++++------------
 1 file changed, 22 insertions(+), 20 deletions(-)
diff mbox series

Patch

diff --git a/drivers/media/platform/vimc/vimc-core.c b/drivers/media/platform/vimc/vimc-core.c
index 1f8498837646..dab01cbc31d2 100644
--- a/drivers/media/platform/vimc/vimc-core.c
+++ b/drivers/media/platform/vimc/vimc-core.c
@@ -160,24 +160,6 @@  static int vimc_create_links(struct vimc_device *vimc)
 	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 @@  static int vimc_register_devices(struct vimc_device *vimc)
 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);