diff options
| author | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2017-02-03 18:16:18 -0500 |
|---|---|---|
| committer | Mark Brown <broonie@kernel.org> | 2017-02-04 05:37:25 -0500 |
| commit | 3eaeb4756336ad884a2a8eef3ca9e12845fb5391 (patch) | |
| tree | fc52e7ac67545c33f60a05179562a2ebecc076c3 /drivers/regulator/devres.c | |
| 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/regulator/devres.c')
| -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) | |||
| 120 | } | 120 | } |
| 121 | EXPORT_SYMBOL_GPL(devm_regulator_put); | 121 | EXPORT_SYMBOL_GPL(devm_regulator_put); |
| 122 | 122 | ||
| 123 | struct regulator_bulk_devres { | ||
| 124 | struct regulator_bulk_data *consumers; | ||
| 125 | int num_consumers; | ||
| 126 | }; | ||
| 127 | |||
| 128 | static void devm_regulator_bulk_release(struct device *dev, void *res) | ||
| 129 | { | ||
| 130 | struct regulator_bulk_devres *devres = res; | ||
| 131 | |||
| 132 | regulator_bulk_free(devres->num_consumers, devres->consumers); | ||
| 133 | } | ||
| 134 | |||
| 123 | /** | 135 | /** |
| 124 | * devm_regulator_bulk_get - managed get multiple regulator consumers | 136 | * devm_regulator_bulk_get - managed get multiple regulator consumers |
| 125 | * | 137 | * |
| @@ -138,29 +150,22 @@ EXPORT_SYMBOL_GPL(devm_regulator_put); | |||
| 138 | int devm_regulator_bulk_get(struct device *dev, int num_consumers, | 150 | int devm_regulator_bulk_get(struct device *dev, int num_consumers, |
| 139 | struct regulator_bulk_data *consumers) | 151 | struct regulator_bulk_data *consumers) |
| 140 | { | 152 | { |
| 141 | int i; | 153 | struct regulator_bulk_devres *devres; |
| 142 | int ret; | 154 | int ret; |
| 143 | 155 | ||
| 144 | for (i = 0; i < num_consumers; i++) | 156 | devres = devres_alloc(devm_regulator_bulk_release, |
| 145 | consumers[i].consumer = NULL; | 157 | sizeof(*devres), GFP_KERNEL); |
| 146 | 158 | if (!devres) | |
| 147 | for (i = 0; i < num_consumers; i++) { | 159 | return -ENOMEM; |
| 148 | consumers[i].consumer = devm_regulator_get(dev, | ||
| 149 | consumers[i].supply); | ||
| 150 | if (IS_ERR(consumers[i].consumer)) { | ||
| 151 | ret = PTR_ERR(consumers[i].consumer); | ||
| 152 | dev_err(dev, "Failed to get supply '%s': %d\n", | ||
| 153 | consumers[i].supply, ret); | ||
| 154 | consumers[i].consumer = NULL; | ||
| 155 | goto err; | ||
| 156 | } | ||
| 157 | } | ||
| 158 | |||
| 159 | return 0; | ||
| 160 | 160 | ||
| 161 | err: | 161 | ret = regulator_bulk_get(dev, num_consumers, consumers); |
| 162 | for (i = 0; i < num_consumers && consumers[i].consumer; i++) | 162 | if (!ret) { |
| 163 | devm_regulator_put(consumers[i].consumer); | 163 | devres->consumers = consumers; |
| 164 | devres->num_consumers = num_consumers; | ||
| 165 | devres_add(dev, devres); | ||
| 166 | } else { | ||
| 167 | devres_free(devres); | ||
| 168 | } | ||
| 164 | 169 | ||
| 165 | return ret; | 170 | return ret; |
| 166 | } | 171 | } |
