diff options
author | Bengt Jonsson <bengt.g.jonsson@stericsson.com> | 2012-01-13 10:30:31 -0500 |
---|---|---|
committer | Mark Brown <broonie@opensource.wolfsonmicro.com> | 2012-01-20 07:01:29 -0500 |
commit | 38e968380b27d6c0f4b68bdd6e3161f8a7effe38 (patch) | |
tree | f7b53215a90e4e115d429592cfa0bee6bc2e876a /drivers/regulator/db8500-prcmu.c | |
parent | c835e1c00eda6f8f6c6bce49b2d89208f3a184dc (diff) |
regulators/db8500: split off shared dbx500 code
As we progress with DB5500 and future voltage domain regulators
based on very similar hardware as found in the DB8500 PRCMU,
it makes sense to split off the generic parts and introduce
some generic debug code for the DBx500 regulators. This patch
accoplish a basic abstraction of the DBx500 voltage domain
regulators.
Signed-off-by: Bengt Jonsson <bengt.g.jonsson@stericsson.com>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Diffstat (limited to 'drivers/regulator/db8500-prcmu.c')
-rw-r--r-- | drivers/regulator/db8500-prcmu.c | 118 |
1 files changed, 32 insertions, 86 deletions
diff --git a/drivers/regulator/db8500-prcmu.c b/drivers/regulator/db8500-prcmu.c index 515443fcd26b..4bd25e75efa0 100644 --- a/drivers/regulator/db8500-prcmu.c +++ b/drivers/regulator/db8500-prcmu.c | |||
@@ -18,74 +18,11 @@ | |||
18 | #include <linux/regulator/machine.h> | 18 | #include <linux/regulator/machine.h> |
19 | #include <linux/regulator/db8500-prcmu.h> | 19 | #include <linux/regulator/db8500-prcmu.h> |
20 | #include <linux/module.h> | 20 | #include <linux/module.h> |
21 | 21 | #include "dbx500-prcmu.h" | |
22 | /* | ||
23 | * power state reference count | ||
24 | */ | ||
25 | static int power_state_active_cnt; /* will initialize to zero */ | ||
26 | static DEFINE_SPINLOCK(power_state_active_lock); | ||
27 | |||
28 | static void power_state_active_enable(void) | ||
29 | { | ||
30 | unsigned long flags; | ||
31 | |||
32 | spin_lock_irqsave(&power_state_active_lock, flags); | ||
33 | power_state_active_cnt++; | ||
34 | spin_unlock_irqrestore(&power_state_active_lock, flags); | ||
35 | } | ||
36 | |||
37 | static int power_state_active_disable(void) | ||
38 | { | ||
39 | int ret = 0; | ||
40 | unsigned long flags; | ||
41 | |||
42 | spin_lock_irqsave(&power_state_active_lock, flags); | ||
43 | if (power_state_active_cnt <= 0) { | ||
44 | pr_err("power state: unbalanced enable/disable calls\n"); | ||
45 | ret = -EINVAL; | ||
46 | goto out; | ||
47 | } | ||
48 | |||
49 | power_state_active_cnt--; | ||
50 | out: | ||
51 | spin_unlock_irqrestore(&power_state_active_lock, flags); | ||
52 | return ret; | ||
53 | } | ||
54 | |||
55 | /* | ||
56 | * Exported interface for CPUIdle only. This function is called when interrupts | ||
57 | * are turned off. Hence, no locking. | ||
58 | */ | ||
59 | int power_state_active_is_enabled(void) | ||
60 | { | ||
61 | return (power_state_active_cnt > 0); | ||
62 | } | ||
63 | |||
64 | /** | ||
65 | * struct db8500_regulator_info - db8500 regulator information | ||
66 | * @dev: device pointer | ||
67 | * @desc: regulator description | ||
68 | * @rdev: regulator device pointer | ||
69 | * @is_enabled: status of the regulator | ||
70 | * @epod_id: id for EPOD (power domain) | ||
71 | * @is_ramret: RAM retention switch for EPOD (power domain) | ||
72 | * @operating_point: operating point (only for vape, to be removed) | ||
73 | * | ||
74 | */ | ||
75 | struct db8500_regulator_info { | ||
76 | struct device *dev; | ||
77 | struct regulator_desc desc; | ||
78 | struct regulator_dev *rdev; | ||
79 | bool is_enabled; | ||
80 | u16 epod_id; | ||
81 | bool is_ramret; | ||
82 | bool exclude_from_power_state; | ||
83 | unsigned int operating_point; | ||
84 | }; | ||
85 | 22 | ||
86 | static int db8500_regulator_enable(struct regulator_dev *rdev) | 23 | static int db8500_regulator_enable(struct regulator_dev *rdev) |
87 | { | 24 | { |
88 | struct db8500_regulator_info *info = rdev_get_drvdata(rdev); | 25 | struct dbx500_regulator_info *info = rdev_get_drvdata(rdev); |
89 | 26 | ||
90 | if (info == NULL) | 27 | if (info == NULL) |
91 | return -EINVAL; | 28 | return -EINVAL; |
@@ -93,16 +30,18 @@ static int db8500_regulator_enable(struct regulator_dev *rdev) | |||
93 | dev_vdbg(rdev_get_dev(rdev), "regulator-%s-enable\n", | 30 | dev_vdbg(rdev_get_dev(rdev), "regulator-%s-enable\n", |
94 | info->desc.name); | 31 | info->desc.name); |
95 | 32 | ||
96 | info->is_enabled = true; | 33 | if (!info->is_enabled) { |
97 | if (!info->exclude_from_power_state) | 34 | info->is_enabled = true; |
98 | power_state_active_enable(); | 35 | if (!info->exclude_from_power_state) |
36 | power_state_active_enable(); | ||
37 | } | ||
99 | 38 | ||
100 | return 0; | 39 | return 0; |
101 | } | 40 | } |
102 | 41 | ||
103 | static int db8500_regulator_disable(struct regulator_dev *rdev) | 42 | static int db8500_regulator_disable(struct regulator_dev *rdev) |
104 | { | 43 | { |
105 | struct db8500_regulator_info *info = rdev_get_drvdata(rdev); | 44 | struct dbx500_regulator_info *info = rdev_get_drvdata(rdev); |
106 | int ret = 0; | 45 | int ret = 0; |
107 | 46 | ||
108 | if (info == NULL) | 47 | if (info == NULL) |
@@ -111,16 +50,18 @@ static int db8500_regulator_disable(struct regulator_dev *rdev) | |||
111 | dev_vdbg(rdev_get_dev(rdev), "regulator-%s-disable\n", | 50 | dev_vdbg(rdev_get_dev(rdev), "regulator-%s-disable\n", |
112 | info->desc.name); | 51 | info->desc.name); |
113 | 52 | ||
114 | info->is_enabled = false; | 53 | if (info->is_enabled) { |
115 | if (!info->exclude_from_power_state) | 54 | info->is_enabled = false; |
116 | ret = power_state_active_disable(); | 55 | if (!info->exclude_from_power_state) |
56 | ret = power_state_active_disable(); | ||
57 | } | ||
117 | 58 | ||
118 | return ret; | 59 | return ret; |
119 | } | 60 | } |
120 | 61 | ||
121 | static int db8500_regulator_is_enabled(struct regulator_dev *rdev) | 62 | static int db8500_regulator_is_enabled(struct regulator_dev *rdev) |
122 | { | 63 | { |
123 | struct db8500_regulator_info *info = rdev_get_drvdata(rdev); | 64 | struct dbx500_regulator_info *info = rdev_get_drvdata(rdev); |
124 | 65 | ||
125 | if (info == NULL) | 66 | if (info == NULL) |
126 | return -EINVAL; | 67 | return -EINVAL; |
@@ -197,7 +138,7 @@ static int disable_epod(u16 epod_id, bool ramret) | |||
197 | */ | 138 | */ |
198 | static int db8500_regulator_switch_enable(struct regulator_dev *rdev) | 139 | static int db8500_regulator_switch_enable(struct regulator_dev *rdev) |
199 | { | 140 | { |
200 | struct db8500_regulator_info *info = rdev_get_drvdata(rdev); | 141 | struct dbx500_regulator_info *info = rdev_get_drvdata(rdev); |
201 | int ret; | 142 | int ret; |
202 | 143 | ||
203 | if (info == NULL) | 144 | if (info == NULL) |
@@ -221,7 +162,7 @@ out: | |||
221 | 162 | ||
222 | static int db8500_regulator_switch_disable(struct regulator_dev *rdev) | 163 | static int db8500_regulator_switch_disable(struct regulator_dev *rdev) |
223 | { | 164 | { |
224 | struct db8500_regulator_info *info = rdev_get_drvdata(rdev); | 165 | struct dbx500_regulator_info *info = rdev_get_drvdata(rdev); |
225 | int ret; | 166 | int ret; |
226 | 167 | ||
227 | if (info == NULL) | 168 | if (info == NULL) |
@@ -245,7 +186,7 @@ out: | |||
245 | 186 | ||
246 | static int db8500_regulator_switch_is_enabled(struct regulator_dev *rdev) | 187 | static int db8500_regulator_switch_is_enabled(struct regulator_dev *rdev) |
247 | { | 188 | { |
248 | struct db8500_regulator_info *info = rdev_get_drvdata(rdev); | 189 | struct dbx500_regulator_info *info = rdev_get_drvdata(rdev); |
249 | 190 | ||
250 | if (info == NULL) | 191 | if (info == NULL) |
251 | return -EINVAL; | 192 | return -EINVAL; |
@@ -266,8 +207,8 @@ static struct regulator_ops db8500_regulator_switch_ops = { | |||
266 | /* | 207 | /* |
267 | * Regulator information | 208 | * Regulator information |
268 | */ | 209 | */ |
269 | static struct db8500_regulator_info | 210 | static struct dbx500_regulator_info |
270 | db8500_regulator_info[DB8500_NUM_REGULATORS] = { | 211 | dbx500_regulator_info[DB8500_NUM_REGULATORS] = { |
271 | [DB8500_REGULATOR_VAPE] = { | 212 | [DB8500_REGULATOR_VAPE] = { |
272 | .desc = { | 213 | .desc = { |
273 | .name = "db8500-vape", | 214 | .name = "db8500-vape", |
@@ -476,12 +417,12 @@ static int __devinit db8500_regulator_probe(struct platform_device *pdev) | |||
476 | int i, err; | 417 | int i, err; |
477 | 418 | ||
478 | /* register all regulators */ | 419 | /* register all regulators */ |
479 | for (i = 0; i < ARRAY_SIZE(db8500_regulator_info); i++) { | 420 | for (i = 0; i < ARRAY_SIZE(dbx500_regulator_info); i++) { |
480 | struct db8500_regulator_info *info; | 421 | struct dbx500_regulator_info *info; |
481 | struct regulator_init_data *init_data = &db8500_init_data[i]; | 422 | struct regulator_init_data *init_data = &db8500_init_data[i]; |
482 | 423 | ||
483 | /* assign per-regulator data */ | 424 | /* assign per-regulator data */ |
484 | info = &db8500_regulator_info[i]; | 425 | info = &dbx500_regulator_info[i]; |
485 | info->dev = &pdev->dev; | 426 | info->dev = &pdev->dev; |
486 | 427 | ||
487 | /* register with the regulator framework */ | 428 | /* register with the regulator framework */ |
@@ -494,7 +435,7 @@ static int __devinit db8500_regulator_probe(struct platform_device *pdev) | |||
494 | 435 | ||
495 | /* if failing, unregister all earlier regulators */ | 436 | /* if failing, unregister all earlier regulators */ |
496 | while (--i >= 0) { | 437 | while (--i >= 0) { |
497 | info = &db8500_regulator_info[i]; | 438 | info = &dbx500_regulator_info[i]; |
498 | regulator_unregister(info->rdev); | 439 | regulator_unregister(info->rdev); |
499 | } | 440 | } |
500 | return err; | 441 | return err; |
@@ -503,17 +444,22 @@ static int __devinit db8500_regulator_probe(struct platform_device *pdev) | |||
503 | dev_dbg(rdev_get_dev(info->rdev), | 444 | dev_dbg(rdev_get_dev(info->rdev), |
504 | "regulator-%s-probed\n", info->desc.name); | 445 | "regulator-%s-probed\n", info->desc.name); |
505 | } | 446 | } |
447 | err = ux500_regulator_debug_init(pdev, | ||
448 | dbx500_regulator_info, | ||
449 | ARRAY_SIZE(dbx500_regulator_info)); | ||
506 | 450 | ||
507 | return 0; | 451 | return err; |
508 | } | 452 | } |
509 | 453 | ||
510 | static int __exit db8500_regulator_remove(struct platform_device *pdev) | 454 | static int __exit db8500_regulator_remove(struct platform_device *pdev) |
511 | { | 455 | { |
512 | int i; | 456 | int i; |
513 | 457 | ||
514 | for (i = 0; i < ARRAY_SIZE(db8500_regulator_info); i++) { | 458 | ux500_regulator_debug_exit(); |
515 | struct db8500_regulator_info *info; | 459 | |
516 | info = &db8500_regulator_info[i]; | 460 | for (i = 0; i < ARRAY_SIZE(dbx500_regulator_info); i++) { |
461 | struct dbx500_regulator_info *info; | ||
462 | info = &dbx500_regulator_info[i]; | ||
517 | 463 | ||
518 | dev_vdbg(rdev_get_dev(info->rdev), | 464 | dev_vdbg(rdev_get_dev(info->rdev), |
519 | "regulator-%s-remove\n", info->desc.name); | 465 | "regulator-%s-remove\n", info->desc.name); |