Merge branch 'stable/bug.fixes' of git://git.kernel.org/pub/scm/linux/kernel/git...
[pandora-kernel.git] / drivers / regulator / db8500-prcmu.c
1 /*
2  * Copyright (C) ST-Ericsson SA 2010
3  *
4  * License Terms: GNU General Public License v2
5  * Authors: Sundar Iyer <sundar.iyer@stericsson.com> for ST-Ericsson
6  *          Bengt Jonsson <bengt.g.jonsson@stericsson.com> for ST-Ericsson
7  *
8  * Power domain regulators on DB8500
9  */
10
11 #include <linux/kernel.h>
12 #include <linux/init.h>
13 #include <linux/err.h>
14 #include <linux/spinlock.h>
15 #include <linux/platform_device.h>
16 #include <linux/mfd/db8500-prcmu.h>
17 #include <linux/regulator/driver.h>
18 #include <linux/regulator/machine.h>
19 #include <linux/regulator/db8500-prcmu.h>
20
21 /*
22  * power state reference count
23  */
24 static int power_state_active_cnt; /* will initialize to zero */
25 static DEFINE_SPINLOCK(power_state_active_lock);
26
27 static void power_state_active_enable(void)
28 {
29         unsigned long flags;
30
31         spin_lock_irqsave(&power_state_active_lock, flags);
32         power_state_active_cnt++;
33         spin_unlock_irqrestore(&power_state_active_lock, flags);
34 }
35
36 static int power_state_active_disable(void)
37 {
38         int ret = 0;
39         unsigned long flags;
40
41         spin_lock_irqsave(&power_state_active_lock, flags);
42         if (power_state_active_cnt <= 0) {
43                 pr_err("power state: unbalanced enable/disable calls\n");
44                 ret = -EINVAL;
45                 goto out;
46         }
47
48         power_state_active_cnt--;
49 out:
50         spin_unlock_irqrestore(&power_state_active_lock, flags);
51         return ret;
52 }
53
54 /*
55  * Exported interface for CPUIdle only. This function is called when interrupts
56  * are turned off. Hence, no locking.
57  */
58 int power_state_active_is_enabled(void)
59 {
60         return (power_state_active_cnt > 0);
61 }
62
63 /**
64  * struct db8500_regulator_info - db8500 regulator information
65  * @dev: device pointer
66  * @desc: regulator description
67  * @rdev: regulator device pointer
68  * @is_enabled: status of the regulator
69  * @epod_id: id for EPOD (power domain)
70  * @is_ramret: RAM retention switch for EPOD (power domain)
71  * @operating_point: operating point (only for vape, to be removed)
72  *
73  */
74 struct db8500_regulator_info {
75         struct device *dev;
76         struct regulator_desc desc;
77         struct regulator_dev *rdev;
78         bool is_enabled;
79         u16 epod_id;
80         bool is_ramret;
81         bool exclude_from_power_state;
82         unsigned int operating_point;
83 };
84
85 static int db8500_regulator_enable(struct regulator_dev *rdev)
86 {
87         struct db8500_regulator_info *info = rdev_get_drvdata(rdev);
88
89         if (info == NULL)
90                 return -EINVAL;
91
92         dev_vdbg(rdev_get_dev(rdev), "regulator-%s-enable\n",
93                 info->desc.name);
94
95         info->is_enabled = true;
96         if (!info->exclude_from_power_state)
97                 power_state_active_enable();
98
99         return 0;
100 }
101
102 static int db8500_regulator_disable(struct regulator_dev *rdev)
103 {
104         struct db8500_regulator_info *info = rdev_get_drvdata(rdev);
105         int ret = 0;
106
107         if (info == NULL)
108                 return -EINVAL;
109
110         dev_vdbg(rdev_get_dev(rdev), "regulator-%s-disable\n",
111                 info->desc.name);
112
113         info->is_enabled = false;
114         if (!info->exclude_from_power_state)
115                 ret = power_state_active_disable();
116
117         return ret;
118 }
119
120 static int db8500_regulator_is_enabled(struct regulator_dev *rdev)
121 {
122         struct db8500_regulator_info *info = rdev_get_drvdata(rdev);
123
124         if (info == NULL)
125                 return -EINVAL;
126
127         dev_vdbg(rdev_get_dev(rdev), "regulator-%s-is_enabled (is_enabled):"
128                 " %i\n", info->desc.name, info->is_enabled);
129
130         return info->is_enabled;
131 }
132
133 /* db8500 regulator operations */
134 static struct regulator_ops db8500_regulator_ops = {
135         .enable                 = db8500_regulator_enable,
136         .disable                = db8500_regulator_disable,
137         .is_enabled             = db8500_regulator_is_enabled,
138 };
139
140 /*
141  * EPOD control
142  */
143 static bool epod_on[NUM_EPOD_ID];
144 static bool epod_ramret[NUM_EPOD_ID];
145
146 static int enable_epod(u16 epod_id, bool ramret)
147 {
148         int ret;
149
150         if (ramret) {
151                 if (!epod_on[epod_id]) {
152                         ret = prcmu_set_epod(epod_id, EPOD_STATE_RAMRET);
153                         if (ret < 0)
154                                 return ret;
155                 }
156                 epod_ramret[epod_id] = true;
157         } else {
158                 ret = prcmu_set_epod(epod_id, EPOD_STATE_ON);
159                 if (ret < 0)
160                         return ret;
161                 epod_on[epod_id] = true;
162         }
163
164         return 0;
165 }
166
167 static int disable_epod(u16 epod_id, bool ramret)
168 {
169         int ret;
170
171         if (ramret) {
172                 if (!epod_on[epod_id]) {
173                         ret = prcmu_set_epod(epod_id, EPOD_STATE_OFF);
174                         if (ret < 0)
175                                 return ret;
176                 }
177                 epod_ramret[epod_id] = false;
178         } else {
179                 if (epod_ramret[epod_id]) {
180                         ret = prcmu_set_epod(epod_id, EPOD_STATE_RAMRET);
181                         if (ret < 0)
182                                 return ret;
183                 } else {
184                         ret = prcmu_set_epod(epod_id, EPOD_STATE_OFF);
185                         if (ret < 0)
186                                 return ret;
187                 }
188                 epod_on[epod_id] = false;
189         }
190
191         return 0;
192 }
193
194 /*
195  * Regulator switch
196  */
197 static int db8500_regulator_switch_enable(struct regulator_dev *rdev)
198 {
199         struct db8500_regulator_info *info = rdev_get_drvdata(rdev);
200         int ret;
201
202         if (info == NULL)
203                 return -EINVAL;
204
205         dev_vdbg(rdev_get_dev(rdev), "regulator-switch-%s-enable\n",
206                 info->desc.name);
207
208         ret = enable_epod(info->epod_id, info->is_ramret);
209         if (ret < 0) {
210                 dev_err(rdev_get_dev(rdev),
211                         "regulator-switch-%s-enable: prcmu call failed\n",
212                         info->desc.name);
213                 goto out;
214         }
215
216         info->is_enabled = true;
217 out:
218         return ret;
219 }
220
221 static int db8500_regulator_switch_disable(struct regulator_dev *rdev)
222 {
223         struct db8500_regulator_info *info = rdev_get_drvdata(rdev);
224         int ret;
225
226         if (info == NULL)
227                 return -EINVAL;
228
229         dev_vdbg(rdev_get_dev(rdev), "regulator-switch-%s-disable\n",
230                 info->desc.name);
231
232         ret = disable_epod(info->epod_id, info->is_ramret);
233         if (ret < 0) {
234                 dev_err(rdev_get_dev(rdev),
235                         "regulator_switch-%s-disable: prcmu call failed\n",
236                         info->desc.name);
237                 goto out;
238         }
239
240         info->is_enabled = 0;
241 out:
242         return ret;
243 }
244
245 static int db8500_regulator_switch_is_enabled(struct regulator_dev *rdev)
246 {
247         struct db8500_regulator_info *info = rdev_get_drvdata(rdev);
248
249         if (info == NULL)
250                 return -EINVAL;
251
252         dev_vdbg(rdev_get_dev(rdev),
253                 "regulator-switch-%s-is_enabled (is_enabled): %i\n",
254                 info->desc.name, info->is_enabled);
255
256         return info->is_enabled;
257 }
258
259 static struct regulator_ops db8500_regulator_switch_ops = {
260         .enable                 = db8500_regulator_switch_enable,
261         .disable                = db8500_regulator_switch_disable,
262         .is_enabled             = db8500_regulator_switch_is_enabled,
263 };
264
265 /*
266  * Regulator information
267  */
268 static struct db8500_regulator_info
269 db8500_regulator_info[DB8500_NUM_REGULATORS] = {
270         [DB8500_REGULATOR_VAPE] = {
271                 .desc = {
272                         .name   = "db8500-vape",
273                         .id     = DB8500_REGULATOR_VAPE,
274                         .ops    = &db8500_regulator_ops,
275                         .type   = REGULATOR_VOLTAGE,
276                         .owner  = THIS_MODULE,
277                 },
278         },
279         [DB8500_REGULATOR_VARM] = {
280                 .desc = {
281                         .name   = "db8500-varm",
282                         .id     = DB8500_REGULATOR_VARM,
283                         .ops    = &db8500_regulator_ops,
284                         .type   = REGULATOR_VOLTAGE,
285                         .owner  = THIS_MODULE,
286                 },
287         },
288         [DB8500_REGULATOR_VMODEM] = {
289                 .desc = {
290                         .name   = "db8500-vmodem",
291                         .id     = DB8500_REGULATOR_VMODEM,
292                         .ops    = &db8500_regulator_ops,
293                         .type   = REGULATOR_VOLTAGE,
294                         .owner  = THIS_MODULE,
295                 },
296         },
297         [DB8500_REGULATOR_VPLL] = {
298                 .desc = {
299                         .name   = "db8500-vpll",
300                         .id     = DB8500_REGULATOR_VPLL,
301                         .ops    = &db8500_regulator_ops,
302                         .type   = REGULATOR_VOLTAGE,
303                         .owner  = THIS_MODULE,
304                 },
305         },
306         [DB8500_REGULATOR_VSMPS1] = {
307                 .desc = {
308                         .name   = "db8500-vsmps1",
309                         .id     = DB8500_REGULATOR_VSMPS1,
310                         .ops    = &db8500_regulator_ops,
311                         .type   = REGULATOR_VOLTAGE,
312                         .owner  = THIS_MODULE,
313                 },
314         },
315         [DB8500_REGULATOR_VSMPS2] = {
316                 .desc = {
317                         .name   = "db8500-vsmps2",
318                         .id     = DB8500_REGULATOR_VSMPS2,
319                         .ops    = &db8500_regulator_ops,
320                         .type   = REGULATOR_VOLTAGE,
321                         .owner  = THIS_MODULE,
322                 },
323                 .exclude_from_power_state = true,
324         },
325         [DB8500_REGULATOR_VSMPS3] = {
326                 .desc = {
327                         .name   = "db8500-vsmps3",
328                         .id     = DB8500_REGULATOR_VSMPS3,
329                         .ops    = &db8500_regulator_ops,
330                         .type   = REGULATOR_VOLTAGE,
331                         .owner  = THIS_MODULE,
332                 },
333         },
334         [DB8500_REGULATOR_VRF1] = {
335                 .desc = {
336                         .name   = "db8500-vrf1",
337                         .id     = DB8500_REGULATOR_VRF1,
338                         .ops    = &db8500_regulator_ops,
339                         .type   = REGULATOR_VOLTAGE,
340                         .owner  = THIS_MODULE,
341                 },
342         },
343         [DB8500_REGULATOR_SWITCH_SVAMMDSP] = {
344                 .desc = {
345                         .name   = "db8500-sva-mmdsp",
346                         .id     = DB8500_REGULATOR_SWITCH_SVAMMDSP,
347                         .ops    = &db8500_regulator_switch_ops,
348                         .type   = REGULATOR_VOLTAGE,
349                         .owner  = THIS_MODULE,
350                 },
351                 .epod_id = EPOD_ID_SVAMMDSP,
352         },
353         [DB8500_REGULATOR_SWITCH_SVAMMDSPRET] = {
354                 .desc = {
355                         .name   = "db8500-sva-mmdsp-ret",
356                         .id     = DB8500_REGULATOR_SWITCH_SVAMMDSPRET,
357                         .ops    = &db8500_regulator_switch_ops,
358                         .type   = REGULATOR_VOLTAGE,
359                         .owner  = THIS_MODULE,
360                 },
361                 .epod_id = EPOD_ID_SVAMMDSP,
362                 .is_ramret = true,
363         },
364         [DB8500_REGULATOR_SWITCH_SVAPIPE] = {
365                 .desc = {
366                         .name   = "db8500-sva-pipe",
367                         .id     = DB8500_REGULATOR_SWITCH_SVAPIPE,
368                         .ops    = &db8500_regulator_switch_ops,
369                         .type   = REGULATOR_VOLTAGE,
370                         .owner  = THIS_MODULE,
371                 },
372                 .epod_id = EPOD_ID_SVAPIPE,
373         },
374         [DB8500_REGULATOR_SWITCH_SIAMMDSP] = {
375                 .desc = {
376                         .name   = "db8500-sia-mmdsp",
377                         .id     = DB8500_REGULATOR_SWITCH_SIAMMDSP,
378                         .ops    = &db8500_regulator_switch_ops,
379                         .type   = REGULATOR_VOLTAGE,
380                         .owner  = THIS_MODULE,
381                 },
382                 .epod_id = EPOD_ID_SIAMMDSP,
383         },
384         [DB8500_REGULATOR_SWITCH_SIAMMDSPRET] = {
385                 .desc = {
386                         .name   = "db8500-sia-mmdsp-ret",
387                         .id     = DB8500_REGULATOR_SWITCH_SIAMMDSPRET,
388                         .ops    = &db8500_regulator_switch_ops,
389                         .type   = REGULATOR_VOLTAGE,
390                         .owner  = THIS_MODULE,
391                 },
392                 .epod_id = EPOD_ID_SIAMMDSP,
393                 .is_ramret = true,
394         },
395         [DB8500_REGULATOR_SWITCH_SIAPIPE] = {
396                 .desc = {
397                         .name   = "db8500-sia-pipe",
398                         .id     = DB8500_REGULATOR_SWITCH_SIAPIPE,
399                         .ops    = &db8500_regulator_switch_ops,
400                         .type   = REGULATOR_VOLTAGE,
401                         .owner  = THIS_MODULE,
402                 },
403                 .epod_id = EPOD_ID_SIAPIPE,
404         },
405         [DB8500_REGULATOR_SWITCH_SGA] = {
406                 .desc = {
407                         .name   = "db8500-sga",
408                         .id     = DB8500_REGULATOR_SWITCH_SGA,
409                         .ops    = &db8500_regulator_switch_ops,
410                         .type   = REGULATOR_VOLTAGE,
411                         .owner  = THIS_MODULE,
412                 },
413                 .epod_id = EPOD_ID_SGA,
414         },
415         [DB8500_REGULATOR_SWITCH_B2R2_MCDE] = {
416                 .desc = {
417                         .name   = "db8500-b2r2-mcde",
418                         .id     = DB8500_REGULATOR_SWITCH_B2R2_MCDE,
419                         .ops    = &db8500_regulator_switch_ops,
420                         .type   = REGULATOR_VOLTAGE,
421                         .owner  = THIS_MODULE,
422                 },
423                 .epod_id = EPOD_ID_B2R2_MCDE,
424         },
425         [DB8500_REGULATOR_SWITCH_ESRAM12] = {
426                 .desc = {
427                         .name   = "db8500-esram12",
428                         .id     = DB8500_REGULATOR_SWITCH_ESRAM12,
429                         .ops    = &db8500_regulator_switch_ops,
430                         .type   = REGULATOR_VOLTAGE,
431                         .owner  = THIS_MODULE,
432                 },
433                 .epod_id        = EPOD_ID_ESRAM12,
434                 .is_enabled     = true,
435         },
436         [DB8500_REGULATOR_SWITCH_ESRAM12RET] = {
437                 .desc = {
438                         .name   = "db8500-esram12-ret",
439                         .id     = DB8500_REGULATOR_SWITCH_ESRAM12RET,
440                         .ops    = &db8500_regulator_switch_ops,
441                         .type   = REGULATOR_VOLTAGE,
442                         .owner  = THIS_MODULE,
443                 },
444                 .epod_id = EPOD_ID_ESRAM12,
445                 .is_ramret = true,
446         },
447         [DB8500_REGULATOR_SWITCH_ESRAM34] = {
448                 .desc = {
449                         .name   = "db8500-esram34",
450                         .id     = DB8500_REGULATOR_SWITCH_ESRAM34,
451                         .ops    = &db8500_regulator_switch_ops,
452                         .type   = REGULATOR_VOLTAGE,
453                         .owner  = THIS_MODULE,
454                 },
455                 .epod_id        = EPOD_ID_ESRAM34,
456                 .is_enabled     = true,
457         },
458         [DB8500_REGULATOR_SWITCH_ESRAM34RET] = {
459                 .desc = {
460                         .name   = "db8500-esram34-ret",
461                         .id     = DB8500_REGULATOR_SWITCH_ESRAM34RET,
462                         .ops    = &db8500_regulator_switch_ops,
463                         .type   = REGULATOR_VOLTAGE,
464                         .owner  = THIS_MODULE,
465                 },
466                 .epod_id = EPOD_ID_ESRAM34,
467                 .is_ramret = true,
468         },
469 };
470
471 static int __devinit db8500_regulator_probe(struct platform_device *pdev)
472 {
473         struct regulator_init_data *db8500_init_data =
474                                         dev_get_platdata(&pdev->dev);
475         int i, err;
476
477         /* register all regulators */
478         for (i = 0; i < ARRAY_SIZE(db8500_regulator_info); i++) {
479                 struct db8500_regulator_info *info;
480                 struct regulator_init_data *init_data = &db8500_init_data[i];
481
482                 /* assign per-regulator data */
483                 info = &db8500_regulator_info[i];
484                 info->dev = &pdev->dev;
485
486                 /* register with the regulator framework */
487                 info->rdev = regulator_register(&info->desc, &pdev->dev,
488                                 init_data, info);
489                 if (IS_ERR(info->rdev)) {
490                         err = PTR_ERR(info->rdev);
491                         dev_err(&pdev->dev, "failed to register %s: err %i\n",
492                                 info->desc.name, err);
493
494                         /* if failing, unregister all earlier regulators */
495                         while (--i >= 0) {
496                                 info = &db8500_regulator_info[i];
497                                 regulator_unregister(info->rdev);
498                         }
499                         return err;
500                 }
501
502                 dev_dbg(rdev_get_dev(info->rdev),
503                         "regulator-%s-probed\n", info->desc.name);
504         }
505
506         return 0;
507 }
508
509 static int __exit db8500_regulator_remove(struct platform_device *pdev)
510 {
511         int i;
512
513         for (i = 0; i < ARRAY_SIZE(db8500_regulator_info); i++) {
514                 struct db8500_regulator_info *info;
515                 info = &db8500_regulator_info[i];
516
517                 dev_vdbg(rdev_get_dev(info->rdev),
518                         "regulator-%s-remove\n", info->desc.name);
519
520                 regulator_unregister(info->rdev);
521         }
522
523         return 0;
524 }
525
526 static struct platform_driver db8500_regulator_driver = {
527         .driver = {
528                 .name = "db8500-prcmu-regulators",
529                 .owner = THIS_MODULE,
530         },
531         .probe = db8500_regulator_probe,
532         .remove = __exit_p(db8500_regulator_remove),
533 };
534
535 static int __init db8500_regulator_init(void)
536 {
537         return platform_driver_register(&db8500_regulator_driver);
538 }
539
540 static void __exit db8500_regulator_exit(void)
541 {
542         platform_driver_unregister(&db8500_regulator_driver);
543 }
544
545 arch_initcall(db8500_regulator_init);
546 module_exit(db8500_regulator_exit);
547
548 MODULE_AUTHOR("STMicroelectronics/ST-Ericsson");
549 MODULE_DESCRIPTION("DB8500 regulator driver");
550 MODULE_LICENSE("GPL v2");