aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/regulator/mc13892-regulator.c39
-rw-r--r--drivers/regulator/mc13xxx-regulator-core.c10
-rw-r--r--drivers/regulator/mc13xxx.h4
3 files changed, 47 insertions, 6 deletions
diff --git a/drivers/regulator/mc13892-regulator.c b/drivers/regulator/mc13892-regulator.c
index 5dd8aaa5cfb8..9891aec47b57 100644
--- a/drivers/regulator/mc13892-regulator.c
+++ b/drivers/regulator/mc13892-regulator.c
@@ -535,15 +535,18 @@ static int mc13892_regulator_probe(struct platform_device *pdev)
535 struct mc13xxx_regulator_init_data *mc13xxx_data; 535 struct mc13xxx_regulator_init_data *mc13xxx_data;
536 struct regulator_config config = { }; 536 struct regulator_config config = { };
537 int i, ret; 537 int i, ret;
538 int num_regulators = 0; 538 int num_regulators = 0, num_parsed;
539 u32 val; 539 u32 val;
540 540
541 num_regulators = mc13xxx_get_num_regulators_dt(pdev); 541 num_regulators = mc13xxx_get_num_regulators_dt(pdev);
542
542 if (num_regulators <= 0 && pdata) 543 if (num_regulators <= 0 && pdata)
543 num_regulators = pdata->num_regulators; 544 num_regulators = pdata->num_regulators;
544 if (num_regulators <= 0) 545 if (num_regulators <= 0)
545 return -EINVAL; 546 return -EINVAL;
546 547
548 num_parsed = num_regulators;
549
547 priv = devm_kzalloc(&pdev->dev, sizeof(*priv) + 550 priv = devm_kzalloc(&pdev->dev, sizeof(*priv) +
548 num_regulators * sizeof(priv->regulators[0]), 551 num_regulators * sizeof(priv->regulators[0]),
549 GFP_KERNEL); 552 GFP_KERNEL);
@@ -586,7 +589,39 @@ static int mc13892_regulator_probe(struct platform_device *pdev)
586 = mc13892_vcam_get_mode; 589 = mc13892_vcam_get_mode;
587 590
588 mc13xxx_data = mc13xxx_parse_regulators_dt(pdev, mc13892_regulators, 591 mc13xxx_data = mc13xxx_parse_regulators_dt(pdev, mc13892_regulators,
589 ARRAY_SIZE(mc13892_regulators)); 592 ARRAY_SIZE(mc13892_regulators),
593 &num_parsed);
594
595 /*
596 * Perform a little sanity check on the regulator tree - if we found
597 * a number of regulators from mc13xxx_get_num_regulators_dt and
598 * then parsed a smaller number in mc13xxx_parse_regulators_dt then
599 * there is a regulator defined in the regulators node which has
600 * not matched any usable regulator in the driver. In this case,
601 * there is one missing and what will happen is the first regulator
602 * will get registered again.
603 *
604 * Fix this by basically making our number of registerable regulators
605 * equal to the number of regulators we parsed. We are allocating
606 * too much memory for priv, but this is unavoidable at this point.
607 *
608 * As an example of how this can happen, try making a typo in your
609 * regulators node (vviohi {} instead of viohi {}) so that the name
610 * does not match..
611 *
612 * The check will basically pass for platform data (non-DT) because
613 * mc13xxx_parse_regulators_dt for !CONFIG_OF will not touch num_parsed.
614 *
615 */
616 if (num_parsed != num_regulators) {
617 dev_warn(&pdev->dev,
618 "parsed %d != regulators %d - check your device tree!\n",
619 num_parsed, num_regulators);
620
621 num_regulators = num_parsed;
622 priv->num_regulators = num_regulators;
623 }
624
590 for (i = 0; i < num_regulators; i++) { 625 for (i = 0; i < num_regulators; i++) {
591 struct regulator_init_data *init_data; 626 struct regulator_init_data *init_data;
592 struct regulator_desc *desc; 627 struct regulator_desc *desc;
diff --git a/drivers/regulator/mc13xxx-regulator-core.c b/drivers/regulator/mc13xxx-regulator-core.c
index 4ed89c654110..2ecf1d8b6a94 100644
--- a/drivers/regulator/mc13xxx-regulator-core.c
+++ b/drivers/regulator/mc13xxx-regulator-core.c
@@ -181,12 +181,14 @@ EXPORT_SYMBOL_GPL(mc13xxx_get_num_regulators_dt);
181 181
182struct mc13xxx_regulator_init_data *mc13xxx_parse_regulators_dt( 182struct mc13xxx_regulator_init_data *mc13xxx_parse_regulators_dt(
183 struct platform_device *pdev, struct mc13xxx_regulator *regulators, 183 struct platform_device *pdev, struct mc13xxx_regulator *regulators,
184 int num_regulators) 184 int num_regulators, int *num_parsed)
185{ 185{
186 struct mc13xxx_regulator_priv *priv = platform_get_drvdata(pdev); 186 struct mc13xxx_regulator_priv *priv = platform_get_drvdata(pdev);
187 struct mc13xxx_regulator_init_data *data, *p; 187 struct mc13xxx_regulator_init_data *data, *p;
188 struct device_node *parent, *child; 188 struct device_node *parent, *child;
189 int i; 189 int i, parsed = 0;
190
191 *num_parsed = 0;
190 192
191 of_node_get(pdev->dev.parent->of_node); 193 of_node_get(pdev->dev.parent->of_node);
192 parent = of_find_node_by_name(pdev->dev.parent->of_node, "regulators"); 194 parent = of_find_node_by_name(pdev->dev.parent->of_node, "regulators");
@@ -203,16 +205,20 @@ struct mc13xxx_regulator_init_data *mc13xxx_parse_regulators_dt(
203 for (i = 0; i < num_regulators; i++) { 205 for (i = 0; i < num_regulators; i++) {
204 if (!of_node_cmp(child->name, 206 if (!of_node_cmp(child->name,
205 regulators[i].desc.name)) { 207 regulators[i].desc.name)) {
208
206 p->id = i; 209 p->id = i;
207 p->init_data = of_get_regulator_init_data( 210 p->init_data = of_get_regulator_init_data(
208 &pdev->dev, child); 211 &pdev->dev, child);
209 p->node = child; 212 p->node = child;
210 p++; 213 p++;
214
215 parsed++;
211 break; 216 break;
212 } 217 }
213 } 218 }
214 } 219 }
215 220
221 *num_parsed = parsed;
216 return data; 222 return data;
217} 223}
218EXPORT_SYMBOL_GPL(mc13xxx_parse_regulators_dt); 224EXPORT_SYMBOL_GPL(mc13xxx_parse_regulators_dt);
diff --git a/drivers/regulator/mc13xxx.h b/drivers/regulator/mc13xxx.h
index 06c8903f182a..007f83387fd6 100644
--- a/drivers/regulator/mc13xxx.h
+++ b/drivers/regulator/mc13xxx.h
@@ -39,7 +39,7 @@ extern int mc13xxx_fixed_regulator_set_voltage(struct regulator_dev *rdev,
39extern int mc13xxx_get_num_regulators_dt(struct platform_device *pdev); 39extern int mc13xxx_get_num_regulators_dt(struct platform_device *pdev);
40extern struct mc13xxx_regulator_init_data *mc13xxx_parse_regulators_dt( 40extern struct mc13xxx_regulator_init_data *mc13xxx_parse_regulators_dt(
41 struct platform_device *pdev, struct mc13xxx_regulator *regulators, 41 struct platform_device *pdev, struct mc13xxx_regulator *regulators,
42 int num_regulators); 42 int num_regulators, int *num_parsed);
43#else 43#else
44static inline int mc13xxx_get_num_regulators_dt(struct platform_device *pdev) 44static inline int mc13xxx_get_num_regulators_dt(struct platform_device *pdev)
45{ 45{
@@ -48,7 +48,7 @@ static inline int mc13xxx_get_num_regulators_dt(struct platform_device *pdev)
48 48
49static inline struct mc13xxx_regulator_init_data *mc13xxx_parse_regulators_dt( 49static inline struct mc13xxx_regulator_init_data *mc13xxx_parse_regulators_dt(
50 struct platform_device *pdev, struct mc13xxx_regulator *regulators, 50 struct platform_device *pdev, struct mc13xxx_regulator *regulators,
51 int num_regulators) 51 int num_regulators, int *num_parsed)
52{ 52{
53 return NULL; 53 return NULL;
54} 54}