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 a3c3785901f5..496002efd961 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c | |||
| @@ -3516,12 +3516,17 @@ regulator_register(const struct regulator_desc *regulator_desc, | |||
| 3516 | return ERR_PTR(-EINVAL); | 3516 | return ERR_PTR(-EINVAL); |
| 3517 | } | 3517 | } |
| 3518 | 3518 | ||
| 3519 | init_data = config->init_data; | ||
| 3520 | |||
| 3521 | rdev = kzalloc(sizeof(struct regulator_dev), GFP_KERNEL); | 3519 | rdev = kzalloc(sizeof(struct regulator_dev), GFP_KERNEL); |
| 3522 | if (rdev == NULL) | 3520 | if (rdev == NULL) |
| 3523 | return ERR_PTR(-ENOMEM); | 3521 | return ERR_PTR(-ENOMEM); |
| 3524 | 3522 | ||
| 3523 | init_data = regulator_of_get_init_data(dev, regulator_desc, | ||
| 3524 | &rdev->dev.of_node); | ||
| 3525 | if (!init_data) { | ||
| 3526 | init_data = config->init_data; | ||
| 3527 | rdev->dev.of_node = of_node_get(config->of_node); | ||
| 3528 | } | ||
| 3529 | |||
| 3525 | mutex_lock(®ulator_list_mutex); | 3530 | mutex_lock(®ulator_list_mutex); |
| 3526 | 3531 | ||
| 3527 | mutex_init(&rdev->mutex); | 3532 | mutex_init(&rdev->mutex); |
| @@ -3548,7 +3553,6 @@ regulator_register(const struct regulator_desc *regulator_desc, | |||
| 3548 | 3553 | ||
| 3549 | /* register with sysfs */ | 3554 | /* register with sysfs */ |
| 3550 | rdev->dev.class = ®ulator_class; | 3555 | rdev->dev.class = ®ulator_class; |
| 3551 | rdev->dev.of_node = of_node_get(config->of_node); | ||
| 3552 | rdev->dev.parent = dev; | 3556 | rdev->dev.parent = dev; |
| 3553 | dev_set_name(&rdev->dev, "regulator.%d", | 3557 | dev_set_name(&rdev->dev, "regulator.%d", |
| 3554 | atomic_inc_return(®ulator_no) - 1); | 3558 | 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 bbe03a1924c0..c35f5f97a147 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. |
| @@ -242,6 +244,8 @@ enum regulator_type { | |||
| 242 | struct regulator_desc { | 244 | struct regulator_desc { |
| 243 | const char *name; | 245 | const char *name; |
| 244 | const char *supply_name; | 246 | const char *supply_name; |
| 247 | const char *of_match; | ||
| 248 | const char *regulators_node; | ||
| 245 | int id; | 249 | int id; |
| 246 | bool continuous_voltage_range; | 250 | bool continuous_voltage_range; |
| 247 | unsigned n_voltages; | 251 | unsigned n_voltages; |
