From 3eaeb4756336ad884a2a8eef3ca9e12845fb5391 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Fri, 3 Feb 2017 15:16:18 -0800 Subject: [PATCH] regulator: core: optimize devm_regulator_bulk_get() 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 Signed-off-by: Mark Brown --- drivers/regulator/devres.c | 43 +++++++++++++++++++++----------------- 1 file changed, 24 insertions(+), 19 deletions(-) diff --git a/drivers/regulator/devres.c b/drivers/regulator/devres.c index 965d1d31ec8c..784e3bf32210 100644 --- a/drivers/regulator/devres.c +++ b/drivers/regulator/devres.c @@ -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,30 +150,23 @@ 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; + devres = devres_alloc(devm_regulator_bulk_release, + sizeof(*devres), GFP_KERNEL); + if (!devres) + return -ENOMEM; - 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; - } + 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 0; - -err: - for (i = 0; i < num_consumers && consumers[i].consumer; i++) - devm_regulator_put(consumers[i].consumer); - return ret; } EXPORT_SYMBOL_GPL(devm_regulator_bulk_get);