diff options
-rw-r--r-- | drivers/regulator/core.c | 10 | ||||
-rw-r--r-- | drivers/regulator/internal.h | 4 | ||||
-rw-r--r-- | drivers/regulator/of_regulator.c | 51 | ||||
-rw-r--r-- | include/linux/regulator/driver.h | 4 |
4 files changed, 66 insertions, 3 deletions
diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index 1e976b6320a2..75aa49085763 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c | |||
@@ -3553,12 +3553,17 @@ regulator_register(const struct regulator_desc *regulator_desc, | |||
3553 | return ERR_PTR(-EINVAL); | 3553 | return ERR_PTR(-EINVAL); |
3554 | } | 3554 | } |
3555 | 3555 | ||
3556 | init_data = config->init_data; | ||
3557 | |||
3558 | rdev = kzalloc(sizeof(struct regulator_dev), GFP_KERNEL); | 3556 | rdev = kzalloc(sizeof(struct regulator_dev), GFP_KERNEL); |
3559 | if (rdev == NULL) | 3557 | if (rdev == NULL) |
3560 | return ERR_PTR(-ENOMEM); | 3558 | return ERR_PTR(-ENOMEM); |
3561 | 3559 | ||
3560 | init_data = regulator_of_get_init_data(dev, regulator_desc, | ||
3561 | &rdev->dev.of_node); | ||
3562 | if (!init_data) { | ||
3563 | init_data = config->init_data; | ||
3564 | rdev->dev.of_node = of_node_get(config->of_node); | ||
3565 | } | ||
3566 | |||
3562 | mutex_lock(®ulator_list_mutex); | 3567 | mutex_lock(®ulator_list_mutex); |
3563 | 3568 | ||
3564 | mutex_init(&rdev->mutex); | 3569 | mutex_init(&rdev->mutex); |
@@ -3585,7 +3590,6 @@ regulator_register(const struct regulator_desc *regulator_desc, | |||
3585 | 3590 | ||
3586 | /* register with sysfs */ | 3591 | /* register with sysfs */ |
3587 | rdev->dev.class = ®ulator_class; | 3592 | rdev->dev.class = ®ulator_class; |
3588 | rdev->dev.of_node = of_node_get(config->of_node); | ||
3589 | rdev->dev.parent = dev; | 3593 | rdev->dev.parent = dev; |
3590 | dev_set_name(&rdev->dev, "regulator.%d", | 3594 | dev_set_name(&rdev->dev, "regulator.%d", |
3591 | atomic_inc_return(®ulator_no) - 1); | 3595 | atomic_inc_return(®ulator_no) - 1); |
diff --git a/drivers/regulator/internal.h b/drivers/regulator/internal.h index 84bbda10c396..a6043ad32ead 100644 --- a/drivers/regulator/internal.h +++ b/drivers/regulator/internal.h | |||
@@ -35,4 +35,8 @@ struct regulator { | |||
35 | struct dentry *debugfs; | 35 | struct dentry *debugfs; |
36 | }; | 36 | }; |
37 | 37 | ||
38 | struct regulator_init_data *regulator_of_get_init_data(struct device *dev, | ||
39 | const struct regulator_desc *desc, | ||
40 | struct device_node **node); | ||
41 | |||
38 | #endif | 42 | #endif |
diff --git a/drivers/regulator/of_regulator.c b/drivers/regulator/of_regulator.c index ee5e67bc8d5b..7a51814abdc5 100644 --- a/drivers/regulator/of_regulator.c +++ b/drivers/regulator/of_regulator.c | |||
@@ -14,8 +14,11 @@ | |||
14 | #include <linux/slab.h> | 14 | #include <linux/slab.h> |
15 | #include <linux/of.h> | 15 | #include <linux/of.h> |
16 | #include <linux/regulator/machine.h> | 16 | #include <linux/regulator/machine.h> |
17 | #include <linux/regulator/driver.h> | ||
17 | #include <linux/regulator/of_regulator.h> | 18 | #include <linux/regulator/of_regulator.h> |
18 | 19 | ||
20 | #include "internal.h" | ||
21 | |||
19 | static void of_get_regulation_constraints(struct device_node *np, | 22 | static void of_get_regulation_constraints(struct device_node *np, |
20 | struct regulator_init_data **init_data) | 23 | struct regulator_init_data **init_data) |
21 | { | 24 | { |
@@ -189,3 +192,51 @@ int of_regulator_match(struct device *dev, struct device_node *node, | |||
189 | return count; | 192 | return count; |
190 | } | 193 | } |
191 | EXPORT_SYMBOL_GPL(of_regulator_match); | 194 | EXPORT_SYMBOL_GPL(of_regulator_match); |
195 | |||
196 | struct regulator_init_data *regulator_of_get_init_data(struct device *dev, | ||
197 | const struct regulator_desc *desc, | ||
198 | struct device_node **node) | ||
199 | { | ||
200 | struct device_node *search, *child; | ||
201 | struct regulator_init_data *init_data = NULL; | ||
202 | const char *name; | ||
203 | |||
204 | if (!dev->of_node || !desc->of_match) | ||
205 | return NULL; | ||
206 | |||
207 | if (desc->regulators_node) | ||
208 | search = of_get_child_by_name(dev->of_node, | ||
209 | desc->regulators_node); | ||
210 | else | ||
211 | search = dev->of_node; | ||
212 | |||
213 | if (!search) { | ||
214 | dev_err(dev, "Failed to find regulator container node\n"); | ||
215 | return NULL; | ||
216 | } | ||
217 | |||
218 | for_each_child_of_node(search, child) { | ||
219 | name = of_get_property(child, "regulator-compatible", NULL); | ||
220 | if (!name) | ||
221 | name = child->name; | ||
222 | |||
223 | if (strcmp(desc->of_match, name)) | ||
224 | continue; | ||
225 | |||
226 | init_data = of_get_regulator_init_data(dev, child); | ||
227 | if (!init_data) { | ||
228 | dev_err(dev, | ||
229 | "failed to parse DT for regulator %s\n", | ||
230 | child->name); | ||
231 | break; | ||
232 | } | ||
233 | |||
234 | of_node_get(child); | ||
235 | *node = child; | ||
236 | break; | ||
237 | } | ||
238 | |||
239 | of_node_put(search); | ||
240 | |||
241 | return init_data; | ||
242 | } | ||
diff --git a/include/linux/regulator/driver.h b/include/linux/regulator/driver.h index efe058f8f746..18f7017deaa5 100644 --- a/include/linux/regulator/driver.h +++ b/include/linux/regulator/driver.h | |||
@@ -203,6 +203,8 @@ enum regulator_type { | |||
203 | * | 203 | * |
204 | * @name: Identifying name for the regulator. | 204 | * @name: Identifying name for the regulator. |
205 | * @supply_name: Identifying the regulator supply | 205 | * @supply_name: Identifying the regulator supply |
206 | * @of_match: Name used to identify regulator in DT. | ||
207 | * @regulators_node: Name of node containing regulator definitions in DT. | ||
206 | * @id: Numerical identifier for the regulator. | 208 | * @id: Numerical identifier for the regulator. |
207 | * @ops: Regulator operations table. | 209 | * @ops: Regulator operations table. |
208 | * @irq: Interrupt number for the regulator. | 210 | * @irq: Interrupt number for the regulator. |
@@ -243,6 +245,8 @@ enum regulator_type { | |||
243 | struct regulator_desc { | 245 | struct regulator_desc { |
244 | const char *name; | 246 | const char *name; |
245 | const char *supply_name; | 247 | const char *supply_name; |
248 | const char *of_match; | ||
249 | const char *regulators_node; | ||
246 | int id; | 250 | int id; |
247 | bool continuous_voltage_range; | 251 | bool continuous_voltage_range; |
248 | unsigned n_voltages; | 252 | unsigned n_voltages; |