component: fix missed cleanup in case of devres failure
authorRussell King <rmk+kernel@arm.linux.org.uk>
Wed, 23 Apr 2014 09:52:17 +0000 (10:52 +0100)
committerRussell King <rmk+kernel@arm.linux.org.uk>
Thu, 3 Jul 2014 10:32:37 +0000 (11:32 +0100)
In try_to_bring_up_master(), we tear down the master's component list
for each error case, except for devres group failure.  Fix this
oversight by making the code less prone to such mistakes.

Acked-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
drivers/base/component.c

index c4778995cd728047d83a284d2e9248bbde89389f..d0ebd4431736381f0dc4c30adfe91653b8787e57 100644 (file)
@@ -113,44 +113,44 @@ static void master_remove_components(struct master *master)
 static int try_to_bring_up_master(struct master *master,
        struct component *component)
 {
-       int ret = 0;
+       int ret;
 
-       if (!master->bound) {
-               /*
-                * Search the list of components, looking for components that
-                * belong to this master, and attach them to the master.
-                */
-               if (master->ops->add_components(master->dev, master)) {
-                       /* Failed to find all components */
-                       master_remove_components(master);
-                       ret = 0;
-                       goto out;
-               }
+       if (master->bound)
+               return 0;
 
-               if (component && component->master != master) {
-                       master_remove_components(master);
-                       ret = 0;
-                       goto out;
-               }
+       /*
+        * Search the list of components, looking for components that
+        * belong to this master, and attach them to the master.
+        */
+       if (master->ops->add_components(master->dev, master)) {
+               /* Failed to find all components */
+               ret = 0;
+               goto out;
+       }
 
-               if (!devres_open_group(master->dev, NULL, GFP_KERNEL)) {
-                       ret = -ENOMEM;
-                       goto out;
-               }
+       if (component && component->master != master) {
+               ret = 0;
+               goto out;
+       }
 
-               /* Found all components */
-               ret = master->ops->bind(master->dev);
-               if (ret < 0) {
-                       devres_release_group(master->dev, NULL);
-                       dev_info(master->dev, "master bind failed: %d\n", ret);
-                       master_remove_components(master);
-                       goto out;
-               }
+       if (!devres_open_group(master->dev, NULL, GFP_KERNEL)) {
+               ret = -ENOMEM;
+               goto out;
+       }
 
-               master->bound = true;
-               ret = 1;
+       /* Found all components */
+       ret = master->ops->bind(master->dev);
+       if (ret < 0) {
+               devres_release_group(master->dev, NULL);
+               dev_info(master->dev, "master bind failed: %d\n", ret);
+               goto out;
        }
+
+       master->bound = true;
+       return 1;
+
 out:
+       master_remove_components(master);
 
        return ret;
 }