Merge tag 'lsk-v3.10-15.05-android' into develop-3.10
[firefly-linux-kernel-4.4.55.git] / drivers / regulator / devres.c
1 /*
2  * devres.c  --  Voltage/Current Regulator framework devres implementation.
3  *
4  * Copyright 2013 Linaro Ltd
5  *
6  *  This program is free software; you can redistribute  it and/or modify it
7  *  under  the terms of  the GNU General  Public License as published by the
8  *  Free Software Foundation;  either version 2 of the  License, or (at your
9  *  option) any later version.
10  *
11  */
12
13 #include <linux/kernel.h>
14 #include <linux/err.h>
15 #include <linux/regmap.h>
16 #include <linux/regulator/consumer.h>
17 #include <linux/regulator/driver.h>
18 #include <linux/module.h>
19
20 #include "internal.h"
21
22 enum {
23         NORMAL_GET,
24         EXCLUSIVE_GET,
25         OPTIONAL_GET,
26 };
27
28 static void devm_regulator_release(struct device *dev, void *res)
29 {
30         regulator_put(*(struct regulator **)res);
31 }
32
33 static struct regulator *_devm_regulator_get(struct device *dev, const char *id,
34                                              int get_type)
35 {
36         struct regulator **ptr, *regulator;
37
38         ptr = devres_alloc(devm_regulator_release, sizeof(*ptr), GFP_KERNEL);
39         if (!ptr)
40                 return ERR_PTR(-ENOMEM);
41
42         switch (get_type) {
43         case NORMAL_GET:
44                 regulator = regulator_get(dev, id);
45                 break;
46         case EXCLUSIVE_GET:
47                 regulator = regulator_get_exclusive(dev, id);
48                 break;
49         case OPTIONAL_GET:
50                 regulator = regulator_get_optional(dev, id);
51                 break;
52         default:
53                 regulator = ERR_PTR(-EINVAL);
54         }
55
56         if (!IS_ERR(regulator)) {
57                 *ptr = regulator;
58                 devres_add(dev, ptr);
59         } else {
60                 devres_free(ptr);
61         }
62
63         return regulator;
64 }
65
66 /**
67  * devm_regulator_get - Resource managed regulator_get()
68  * @dev: device for regulator "consumer"
69  * @id: Supply name or regulator ID.
70  *
71  * Managed regulator_get(). Regulators returned from this function are
72  * automatically regulator_put() on driver detach. See regulator_get() for more
73  * information.
74  */
75 struct regulator *devm_regulator_get(struct device *dev, const char *id)
76 {
77         return _devm_regulator_get(dev, id, NORMAL_GET);
78 }
79 EXPORT_SYMBOL_GPL(devm_regulator_get);
80
81 /**
82  * devm_regulator_get_exclusive - Resource managed regulator_get_exclusive()
83  * @dev: device for regulator "consumer"
84  * @id: Supply name or regulator ID.
85  *
86  * Managed regulator_get_exclusive(). Regulators returned from this function
87  * are automatically regulator_put() on driver detach. See regulator_get() for
88  * more information.
89  */
90 struct regulator *devm_regulator_get_exclusive(struct device *dev,
91                                                const char *id)
92 {
93         return _devm_regulator_get(dev, id, EXCLUSIVE_GET);
94 }
95 EXPORT_SYMBOL_GPL(devm_regulator_get_exclusive);
96
97 /**
98  * devm_regulator_get_optional - Resource managed regulator_get_optional()
99  * @dev: device for regulator "consumer"
100  * @id: Supply name or regulator ID.
101  *
102  * Managed regulator_get_optional(). Regulators returned from this
103  * function are automatically regulator_put() on driver detach. See
104  * regulator_get_optional() for more information.
105  */
106 struct regulator *devm_regulator_get_optional(struct device *dev,
107                                               const char *id)
108 {
109         return _devm_regulator_get(dev, id, OPTIONAL_GET);
110 }
111 EXPORT_SYMBOL_GPL(devm_regulator_get_optional);
112
113 static int devm_regulator_match(struct device *dev, void *res, void *data)
114 {
115         struct regulator **r = res;
116         if (!r || !*r) {
117                 WARN_ON(!r || !*r);
118                 return 0;
119         }
120         return *r == data;
121 }
122
123 /**
124  * devm_regulator_put - Resource managed regulator_put()
125  * @regulator: regulator to free
126  *
127  * Deallocate a regulator allocated with devm_regulator_get(). Normally
128  * this function will not need to be called and the resource management
129  * code will ensure that the resource is freed.
130  */
131 void devm_regulator_put(struct regulator *regulator)
132 {
133         int rc;
134
135         rc = devres_release(regulator->dev, devm_regulator_release,
136                             devm_regulator_match, regulator);
137         if (rc != 0)
138                 WARN_ON(rc);
139 }
140 EXPORT_SYMBOL_GPL(devm_regulator_put);
141
142 /**
143  * devm_regulator_bulk_get - managed get multiple regulator consumers
144  *
145  * @dev:           Device to supply
146  * @num_consumers: Number of consumers to register
147  * @consumers:     Configuration of consumers; clients are stored here.
148  *
149  * @return 0 on success, an errno on failure.
150  *
151  * This helper function allows drivers to get several regulator
152  * consumers in one operation with management, the regulators will
153  * automatically be freed when the device is unbound.  If any of the
154  * regulators cannot be acquired then any regulators that were
155  * allocated will be freed before returning to the caller.
156  */
157 int devm_regulator_bulk_get(struct device *dev, int num_consumers,
158                             struct regulator_bulk_data *consumers)
159 {
160         int i;
161         int ret;
162
163         for (i = 0; i < num_consumers; i++)
164                 consumers[i].consumer = NULL;
165
166         for (i = 0; i < num_consumers; i++) {
167                 consumers[i].consumer = devm_regulator_get(dev,
168                                                            consumers[i].supply);
169                 if (IS_ERR(consumers[i].consumer)) {
170                         ret = PTR_ERR(consumers[i].consumer);
171                         dev_err(dev, "Failed to get supply '%s': %d\n",
172                                 consumers[i].supply, ret);
173                         consumers[i].consumer = NULL;
174                         goto err;
175                 }
176         }
177
178         return 0;
179
180 err:
181         for (i = 0; i < num_consumers && consumers[i].consumer; i++)
182                 devm_regulator_put(consumers[i].consumer);
183
184         return ret;
185 }
186 EXPORT_SYMBOL_GPL(devm_regulator_bulk_get);
187
188 static void devm_rdev_release(struct device *dev, void *res)
189 {
190         regulator_unregister(*(struct regulator_dev **)res);
191 }
192
193 /**
194  * devm_regulator_register - Resource managed regulator_register()
195  * @regulator_desc: regulator to register
196  * @config: runtime configuration for regulator
197  *
198  * Called by regulator drivers to register a regulator.  Returns a
199  * valid pointer to struct regulator_dev on success or an ERR_PTR() on
200  * error.  The regulator will automatically be released when the device
201  * is unbound.
202  */
203 struct regulator_dev *devm_regulator_register(struct device *dev,
204                                   const struct regulator_desc *regulator_desc,
205                                   const struct regulator_config *config)
206 {
207         struct regulator_dev **ptr, *rdev;
208
209         ptr = devres_alloc(devm_rdev_release, sizeof(*ptr),
210                            GFP_KERNEL);
211         if (!ptr)
212                 return ERR_PTR(-ENOMEM);
213
214         rdev = regulator_register(regulator_desc, config);
215         if (!IS_ERR(rdev)) {
216                 *ptr = rdev;
217                 devres_add(dev, ptr);
218         } else {
219                 devres_free(ptr);
220         }
221
222         return rdev;
223 }
224 EXPORT_SYMBOL_GPL(devm_regulator_register);
225
226 static int devm_rdev_match(struct device *dev, void *res, void *data)
227 {
228         struct regulator_dev **r = res;
229         if (!r || !*r) {
230                 WARN_ON(!r || !*r);
231                 return 0;
232         }
233         return *r == data;
234 }
235
236 /**
237  * devm_regulator_unregister - Resource managed regulator_unregister()
238  * @regulator: regulator to free
239  *
240  * Unregister a regulator registered with devm_regulator_register().
241  * Normally this function will not need to be called and the resource
242  * management code will ensure that the resource is freed.
243  */
244 void devm_regulator_unregister(struct device *dev, struct regulator_dev *rdev)
245 {
246         int rc;
247
248         rc = devres_release(dev, devm_rdev_release, devm_rdev_match, rdev);
249         if (rc != 0)
250                 WARN_ON(rc);
251 }
252 EXPORT_SYMBOL_GPL(devm_regulator_unregister);