aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/regulator
diff options
context:
space:
mode:
authorShawn Guo <shawn.guo@linaro.org>2011-12-21 10:00:46 -0500
committerMark Brown <broonie@opensource.wolfsonmicro.com>2011-12-22 06:10:45 -0500
commit93bcb23b38f634e8fb4ddda0d3f4862fda5cedae (patch)
tree9f087497a7511022c8e740c3e16bb3703efc4fda /drivers/regulator
parent3a5d03158d0174ae700e15b63eab2023f27aeb88 (diff)
regulator: mc13892: add device tree probe support
It adds device tree probe support for mc13892-regulator driver. Signed-off-by: Shawn Guo <shawn.guo@linaro.org> Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Diffstat (limited to 'drivers/regulator')
-rw-r--r--drivers/regulator/mc13892-regulator.c43
-rw-r--r--drivers/regulator/mc13xxx-regulator-core.c57
-rw-r--r--drivers/regulator/mc13xxx.h20
3 files changed, 109 insertions, 11 deletions
diff --git a/drivers/regulator/mc13892-regulator.c b/drivers/regulator/mc13892-regulator.c
index 2824804a2892..46bfa4ae2afd 100644
--- a/drivers/regulator/mc13892-regulator.c
+++ b/drivers/regulator/mc13892-regulator.c
@@ -527,18 +527,27 @@ static int __devinit mc13892_regulator_probe(struct platform_device *pdev)
527 struct mc13xxx *mc13892 = dev_get_drvdata(pdev->dev.parent); 527 struct mc13xxx *mc13892 = dev_get_drvdata(pdev->dev.parent);
528 struct mc13xxx_regulator_platform_data *pdata = 528 struct mc13xxx_regulator_platform_data *pdata =
529 dev_get_platdata(&pdev->dev); 529 dev_get_platdata(&pdev->dev);
530 struct mc13xxx_regulator_init_data *init_data; 530 struct mc13xxx_regulator_init_data *mc13xxx_data;
531 int i, ret; 531 int i, ret;
532 int num_regulators = 0;
532 u32 val; 533 u32 val;
533 534
535 num_regulators = mc13xxx_get_num_regulators_dt(pdev);
536 if (num_regulators <= 0 && pdata)
537 num_regulators = pdata->num_regulators;
538 if (num_regulators <= 0)
539 return -EINVAL;
540
534 priv = kzalloc(sizeof(*priv) + 541 priv = kzalloc(sizeof(*priv) +
535 pdata->num_regulators * sizeof(priv->regulators[0]), 542 num_regulators * sizeof(priv->regulators[0]),
536 GFP_KERNEL); 543 GFP_KERNEL);
537 if (!priv) 544 if (!priv)
538 return -ENOMEM; 545 return -ENOMEM;
539 546
547 priv->num_regulators = num_regulators;
540 priv->mc13xxx_regulators = mc13892_regulators; 548 priv->mc13xxx_regulators = mc13892_regulators;
541 priv->mc13xxx = mc13892; 549 priv->mc13xxx = mc13892;
550 platform_set_drvdata(pdev, priv);
542 551
543 mc13xxx_lock(mc13892); 552 mc13xxx_lock(mc13892);
544 ret = mc13xxx_reg_read(mc13892, MC13892_REVISION, &val); 553 ret = mc13xxx_reg_read(mc13892, MC13892_REVISION, &val);
@@ -569,11 +578,27 @@ static int __devinit mc13892_regulator_probe(struct platform_device *pdev)
569 = mc13892_vcam_set_mode; 578 = mc13892_vcam_set_mode;
570 mc13892_regulators[MC13892_VCAM].desc.ops->get_mode 579 mc13892_regulators[MC13892_VCAM].desc.ops->get_mode
571 = mc13892_vcam_get_mode; 580 = mc13892_vcam_get_mode;
572 for (i = 0; i < pdata->num_regulators; i++) { 581
573 init_data = &pdata->regulators[i]; 582 mc13xxx_data = mc13xxx_parse_regulators_dt(pdev, mc13892_regulators,
583 ARRAY_SIZE(mc13892_regulators));
584 for (i = 0; i < num_regulators; i++) {
585 struct regulator_init_data *init_data;
586 struct regulator_desc *desc;
587 struct device_node *node = NULL;
588 int id;
589
590 if (mc13xxx_data) {
591 id = mc13xxx_data[i].id;
592 init_data = mc13xxx_data[i].init_data;
593 node = mc13xxx_data[i].node;
594 } else {
595 id = pdata->regulators[i].id;
596 init_data = pdata->regulators[i].init_data;
597 }
598 desc = &mc13892_regulators[id].desc;
599
574 priv->regulators[i] = regulator_register( 600 priv->regulators[i] = regulator_register(
575 &mc13892_regulators[init_data->id].desc, 601 desc, &pdev->dev, init_data, priv, node);
576 &pdev->dev, init_data->init_data, priv, NULL);
577 602
578 if (IS_ERR(priv->regulators[i])) { 603 if (IS_ERR(priv->regulators[i])) {
579 dev_err(&pdev->dev, "failed to register regulator %s\n", 604 dev_err(&pdev->dev, "failed to register regulator %s\n",
@@ -583,8 +608,6 @@ static int __devinit mc13892_regulator_probe(struct platform_device *pdev)
583 } 608 }
584 } 609 }
585 610
586 platform_set_drvdata(pdev, priv);
587
588 return 0; 611 return 0;
589err: 612err:
590 while (--i >= 0) 613 while (--i >= 0)
@@ -600,13 +623,11 @@ err_free:
600static int __devexit mc13892_regulator_remove(struct platform_device *pdev) 623static int __devexit mc13892_regulator_remove(struct platform_device *pdev)
601{ 624{
602 struct mc13xxx_regulator_priv *priv = platform_get_drvdata(pdev); 625 struct mc13xxx_regulator_priv *priv = platform_get_drvdata(pdev);
603 struct mc13xxx_regulator_platform_data *pdata =
604 dev_get_platdata(&pdev->dev);
605 int i; 626 int i;
606 627
607 platform_set_drvdata(pdev, NULL); 628 platform_set_drvdata(pdev, NULL);
608 629
609 for (i = 0; i < pdata->num_regulators; i++) 630 for (i = 0; i < priv->num_regulators; i++)
610 regulator_unregister(priv->regulators[i]); 631 regulator_unregister(priv->regulators[i]);
611 632
612 kfree(priv); 633 kfree(priv);
diff --git a/drivers/regulator/mc13xxx-regulator-core.c b/drivers/regulator/mc13xxx-regulator-core.c
index 6532853a6ef5..80ecafef1bc3 100644
--- a/drivers/regulator/mc13xxx-regulator-core.c
+++ b/drivers/regulator/mc13xxx-regulator-core.c
@@ -18,12 +18,14 @@
18#include <linux/mfd/mc13xxx.h> 18#include <linux/mfd/mc13xxx.h>
19#include <linux/regulator/machine.h> 19#include <linux/regulator/machine.h>
20#include <linux/regulator/driver.h> 20#include <linux/regulator/driver.h>
21#include <linux/regulator/of_regulator.h>
21#include <linux/platform_device.h> 22#include <linux/platform_device.h>
22#include <linux/kernel.h> 23#include <linux/kernel.h>
23#include <linux/slab.h> 24#include <linux/slab.h>
24#include <linux/init.h> 25#include <linux/init.h>
25#include <linux/err.h> 26#include <linux/err.h>
26#include <linux/module.h> 27#include <linux/module.h>
28#include <linux/of.h>
27#include "mc13xxx.h" 29#include "mc13xxx.h"
28 30
29static int mc13xxx_regulator_enable(struct regulator_dev *rdev) 31static int mc13xxx_regulator_enable(struct regulator_dev *rdev)
@@ -236,6 +238,61 @@ int mc13xxx_sw_regulator_is_enabled(struct regulator_dev *rdev)
236} 238}
237EXPORT_SYMBOL_GPL(mc13xxx_sw_regulator_is_enabled); 239EXPORT_SYMBOL_GPL(mc13xxx_sw_regulator_is_enabled);
238 240
241#ifdef CONFIG_OF
242int __devinit mc13xxx_get_num_regulators_dt(struct platform_device *pdev)
243{
244 struct device_node *parent, *child;
245 int num = 0;
246
247 of_node_get(pdev->dev.parent->of_node);
248 parent = of_find_node_by_name(pdev->dev.parent->of_node, "regulators");
249 if (!parent)
250 return -ENODEV;
251
252 for_each_child_of_node(parent, child)
253 num++;
254
255 return num;
256}
257
258struct mc13xxx_regulator_init_data * __devinit mc13xxx_parse_regulators_dt(
259 struct platform_device *pdev, struct mc13xxx_regulator *regulators,
260 int num_regulators)
261{
262 struct mc13xxx_regulator_priv *priv = platform_get_drvdata(pdev);
263 struct mc13xxx_regulator_init_data *data, *p;
264 struct device_node *parent, *child;
265 int i;
266
267 of_node_get(pdev->dev.parent->of_node);
268 parent = of_find_node_by_name(pdev->dev.parent->of_node, "regulators");
269 if (!parent)
270 return NULL;
271
272 data = devm_kzalloc(&pdev->dev, sizeof(*data) * priv->num_regulators,
273 GFP_KERNEL);
274 if (!data)
275 return NULL;
276 p = data;
277
278 for_each_child_of_node(parent, child) {
279 for (i = 0; i < num_regulators; i++) {
280 if (!of_node_cmp(child->name,
281 regulators[i].desc.name)) {
282 p->id = i;
283 p->init_data = of_get_regulator_init_data(
284 &pdev->dev, child);
285 p->node = child;
286 p++;
287 break;
288 }
289 }
290 }
291
292 return data;
293}
294#endif
295
239MODULE_LICENSE("GPL v2"); 296MODULE_LICENSE("GPL v2");
240MODULE_AUTHOR("Yong Shen <yong.shen@linaro.org>"); 297MODULE_AUTHOR("Yong Shen <yong.shen@linaro.org>");
241MODULE_DESCRIPTION("Regulator Driver for Freescale MC13xxx PMIC"); 298MODULE_DESCRIPTION("Regulator Driver for Freescale MC13xxx PMIC");
diff --git a/drivers/regulator/mc13xxx.h b/drivers/regulator/mc13xxx.h
index 75e383226a87..b3961c658b05 100644
--- a/drivers/regulator/mc13xxx.h
+++ b/drivers/regulator/mc13xxx.h
@@ -29,6 +29,7 @@ struct mc13xxx_regulator_priv {
29 struct mc13xxx *mc13xxx; 29 struct mc13xxx *mc13xxx;
30 u32 powermisc_pwgt_state; 30 u32 powermisc_pwgt_state;
31 struct mc13xxx_regulator *mc13xxx_regulators; 31 struct mc13xxx_regulator *mc13xxx_regulators;
32 int num_regulators;
32 struct regulator_dev *regulators[]; 33 struct regulator_dev *regulators[];
33}; 34};
34 35
@@ -42,6 +43,25 @@ extern int mc13xxx_fixed_regulator_set_voltage(struct regulator_dev *rdev,
42 int min_uV, int max_uV, unsigned *selector); 43 int min_uV, int max_uV, unsigned *selector);
43extern int mc13xxx_fixed_regulator_get_voltage(struct regulator_dev *rdev); 44extern int mc13xxx_fixed_regulator_get_voltage(struct regulator_dev *rdev);
44 45
46#ifdef CONFIG_OF
47extern int mc13xxx_get_num_regulators_dt(struct platform_device *pdev);
48extern struct mc13xxx_regulator_init_data *mc13xxx_parse_regulators_dt(
49 struct platform_device *pdev, struct mc13xxx_regulator *regulators,
50 int num_regulators);
51#else
52static inline int mc13xxx_get_num_regulators_dt(struct platform_device *pdev)
53{
54 return -ENODEV;
55}
56
57static inline struct mc13xxx_regulator_init_data *mc13xxx_parse_regulators_dt(
58 struct platform_device *pdev, struct mc13xxx_regulator *regulators,
59 int num_regulators)
60{
61 return NULL;
62}
63#endif
64
45extern struct regulator_ops mc13xxx_regulator_ops; 65extern struct regulator_ops mc13xxx_regulator_ops;
46extern struct regulator_ops mc13xxx_fixed_regulator_ops; 66extern struct regulator_ops mc13xxx_fixed_regulator_ops;
47 67