diff options
author | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2017-02-03 15:16:18 -0800 |
---|---|---|
committer | Mark Brown <broonie@kernel.org> | 2017-02-04 11:37:25 +0100 |
commit | 3eaeb4756336ad884a2a8eef3ca9e12845fb5391 (patch) | |
tree | fc52e7ac67545c33f60a05179562a2ebecc076c3 /drivers | |
parent | b8c77ff6902baa6ca93ca643bfff2d565801ea30 (diff) |
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 <dmitry.torokhov@gmail.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/regulator/devres.c | 45 |
1 files changed, 25 insertions, 20 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,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; } |