regulator: core: optimize devm_regulator_bulk_get()
authorDmitry Torokhov <dmitry.torokhov@gmail.com>
Fri, 3 Feb 2017 23:16:18 +0000 (15:16 -0800)
committerMark Brown <broonie@kernel.org>
Sat, 4 Feb 2017 10:37:25 +0000 (11:37 +0100)
When performing this bulk operation, there is no need to track every supply
individually. It is more efficient to treat entire group as a single
managed resource.

Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
drivers/regulator/devres.c

index 965d1d31ec8cfc8a523a05f2e1fb8fd135629cd1..784e3bf32210bb74a34934078dc6218a82e2aa6e 100644 (file)
@@ -120,6 +120,18 @@ void devm_regulator_put(struct regulator *regulator)
 }
 EXPORT_SYMBOL_GPL(devm_regulator_put);
 
+struct regulator_bulk_devres {
+       struct regulator_bulk_data *consumers;
+       int num_consumers;
+};
+
+static void devm_regulator_bulk_release(struct device *dev, void *res)
+{
+       struct regulator_bulk_devres *devres = res;
+
+       regulator_bulk_free(devres->num_consumers, devres->consumers);
+}
+
 /**
  * devm_regulator_bulk_get - managed get multiple regulator consumers
  *
@@ -138,29 +150,22 @@ EXPORT_SYMBOL_GPL(devm_regulator_put);
 int devm_regulator_bulk_get(struct device *dev, int num_consumers,
                            struct regulator_bulk_data *consumers)
 {
-       int i;
+       struct regulator_bulk_devres *devres;
        int ret;
 
-       for (i = 0; i < num_consumers; i++)
-               consumers[i].consumer = NULL;
-
-       for (i = 0; i < num_consumers; i++) {
-               consumers[i].consumer = devm_regulator_get(dev,
-                                                          consumers[i].supply);
-               if (IS_ERR(consumers[i].consumer)) {
-                       ret = PTR_ERR(consumers[i].consumer);
-                       dev_err(dev, "Failed to get supply '%s': %d\n",
-                               consumers[i].supply, ret);
-                       consumers[i].consumer = NULL;
-                       goto err;
-               }
-       }
-
-       return 0;
+       devres = devres_alloc(devm_regulator_bulk_release,
+                             sizeof(*devres), GFP_KERNEL);
+       if (!devres)
+               return -ENOMEM;
 
-err:
-       for (i = 0; i < num_consumers && consumers[i].consumer; i++)
-               devm_regulator_put(consumers[i].consumer);
+       ret = regulator_bulk_get(dev, num_consumers, consumers);
+       if (!ret) {
+               devres->consumers = consumers;
+               devres->num_consumers = num_consumers;
+               devres_add(dev, devres);
+       } else {
+               devres_free(devres);
+       }
 
        return ret;
 }