diff options
author | Mark Brown <broonie@linaro.org> | 2013-09-11 08:15:40 -0400 |
---|---|---|
committer | Mark Brown <broonie@linaro.org> | 2013-09-16 19:28:45 -0400 |
commit | 0cdfcc0f9352a4c076fbb51299e2b12a35619a51 (patch) | |
tree | 251c021a984bc746b8e02c37e0d2e59043be657b /drivers | |
parent | cee8e355942c01f408bddf8a53596be1dff7a86b (diff) |
regulator: core: Split devres code out into a separate file
Cut down on the size of core.c a bit more and ensure that the devres
versions of things don't do too much peering inside the internals of
the APIs they wrap.
Signed-off-by: Mark Brown <broonie@linaro.org>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/regulator/Makefile | 2 | ||||
-rw-r--r-- | drivers/regulator/core.c | 252 | ||||
-rw-r--r-- | drivers/regulator/devres.c | 252 | ||||
-rw-r--r-- | drivers/regulator/internal.h | 38 |
4 files changed, 292 insertions, 252 deletions
diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile index 185cce246022..69db4c8bb5c9 100644 --- a/drivers/regulator/Makefile +++ b/drivers/regulator/Makefile | |||
@@ -3,7 +3,7 @@ | |||
3 | # | 3 | # |
4 | 4 | ||
5 | 5 | ||
6 | obj-$(CONFIG_REGULATOR) += core.o dummy.o fixed-helper.o helpers.o | 6 | obj-$(CONFIG_REGULATOR) += core.o dummy.o fixed-helper.o helpers.o devres.o |
7 | obj-$(CONFIG_OF) += of_regulator.o | 7 | obj-$(CONFIG_OF) += of_regulator.o |
8 | obj-$(CONFIG_REGULATOR_FIXED_VOLTAGE) += fixed.o | 8 | obj-$(CONFIG_REGULATOR_FIXED_VOLTAGE) += fixed.o |
9 | obj-$(CONFIG_REGULATOR_VIRTUAL_CONSUMER) += virtual.o | 9 | obj-$(CONFIG_REGULATOR_VIRTUAL_CONSUMER) += virtual.o |
diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index 388397bb3192..906deb7354ed 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c | |||
@@ -36,6 +36,7 @@ | |||
36 | #include <trace/events/regulator.h> | 36 | #include <trace/events/regulator.h> |
37 | 37 | ||
38 | #include "dummy.h" | 38 | #include "dummy.h" |
39 | #include "internal.h" | ||
39 | 40 | ||
40 | #define rdev_crit(rdev, fmt, ...) \ | 41 | #define rdev_crit(rdev, fmt, ...) \ |
41 | pr_crit("%s: " fmt, rdev_get_name(rdev), ##__VA_ARGS__) | 42 | pr_crit("%s: " fmt, rdev_get_name(rdev), ##__VA_ARGS__) |
@@ -82,25 +83,6 @@ struct regulator_enable_gpio { | |||
82 | unsigned int ena_gpio_invert:1; | 83 | unsigned int ena_gpio_invert:1; |
83 | }; | 84 | }; |
84 | 85 | ||
85 | /* | ||
86 | * struct regulator | ||
87 | * | ||
88 | * One for each consumer device. | ||
89 | */ | ||
90 | struct regulator { | ||
91 | struct device *dev; | ||
92 | struct list_head list; | ||
93 | unsigned int always_on:1; | ||
94 | unsigned int bypass:1; | ||
95 | int uA_load; | ||
96 | int min_uV; | ||
97 | int max_uV; | ||
98 | char *supply_name; | ||
99 | struct device_attribute dev_attr; | ||
100 | struct regulator_dev *rdev; | ||
101 | struct dentry *debugfs; | ||
102 | }; | ||
103 | |||
104 | static int _regulator_is_enabled(struct regulator_dev *rdev); | 86 | static int _regulator_is_enabled(struct regulator_dev *rdev); |
105 | static int _regulator_disable(struct regulator_dev *rdev); | 87 | static int _regulator_disable(struct regulator_dev *rdev); |
106 | static int _regulator_get_voltage(struct regulator_dev *rdev); | 88 | static int _regulator_get_voltage(struct regulator_dev *rdev); |
@@ -1334,50 +1316,6 @@ out: | |||
1334 | return regulator; | 1316 | return regulator; |
1335 | } | 1317 | } |
1336 | 1318 | ||
1337 | enum { | ||
1338 | NORMAL_GET, | ||
1339 | EXCLUSIVE_GET, | ||
1340 | OPTIONAL_GET, | ||
1341 | }; | ||
1342 | |||
1343 | static void devm_regulator_release(struct device *dev, void *res) | ||
1344 | { | ||
1345 | regulator_put(*(struct regulator **)res); | ||
1346 | } | ||
1347 | |||
1348 | static struct regulator *_devm_regulator_get(struct device *dev, const char *id, | ||
1349 | int get_type) | ||
1350 | { | ||
1351 | struct regulator **ptr, *regulator; | ||
1352 | |||
1353 | ptr = devres_alloc(devm_regulator_release, sizeof(*ptr), GFP_KERNEL); | ||
1354 | if (!ptr) | ||
1355 | return ERR_PTR(-ENOMEM); | ||
1356 | |||
1357 | switch (get_type) { | ||
1358 | case NORMAL_GET: | ||
1359 | regulator = regulator_get(dev, id); | ||
1360 | break; | ||
1361 | case EXCLUSIVE_GET: | ||
1362 | regulator = regulator_get_exclusive(dev, id); | ||
1363 | break; | ||
1364 | case OPTIONAL_GET: | ||
1365 | regulator = regulator_get_optional(dev, id); | ||
1366 | break; | ||
1367 | default: | ||
1368 | regulator = ERR_PTR(-EINVAL); | ||
1369 | } | ||
1370 | |||
1371 | if (!IS_ERR(regulator)) { | ||
1372 | *ptr = regulator; | ||
1373 | devres_add(dev, ptr); | ||
1374 | } else { | ||
1375 | devres_free(ptr); | ||
1376 | } | ||
1377 | |||
1378 | return regulator; | ||
1379 | } | ||
1380 | |||
1381 | /** | 1319 | /** |
1382 | * regulator_get - lookup and obtain a reference to a regulator. | 1320 | * regulator_get - lookup and obtain a reference to a regulator. |
1383 | * @dev: device for regulator "consumer" | 1321 | * @dev: device for regulator "consumer" |
@@ -1398,21 +1336,6 @@ struct regulator *regulator_get(struct device *dev, const char *id) | |||
1398 | EXPORT_SYMBOL_GPL(regulator_get); | 1336 | EXPORT_SYMBOL_GPL(regulator_get); |
1399 | 1337 | ||
1400 | /** | 1338 | /** |
1401 | * devm_regulator_get - Resource managed regulator_get() | ||
1402 | * @dev: device for regulator "consumer" | ||
1403 | * @id: Supply name or regulator ID. | ||
1404 | * | ||
1405 | * Managed regulator_get(). Regulators returned from this function are | ||
1406 | * automatically regulator_put() on driver detach. See regulator_get() for more | ||
1407 | * information. | ||
1408 | */ | ||
1409 | struct regulator *devm_regulator_get(struct device *dev, const char *id) | ||
1410 | { | ||
1411 | return _devm_regulator_get(dev, id, NORMAL_GET); | ||
1412 | } | ||
1413 | EXPORT_SYMBOL_GPL(devm_regulator_get); | ||
1414 | |||
1415 | /** | ||
1416 | * regulator_get_exclusive - obtain exclusive access to a regulator. | 1339 | * regulator_get_exclusive - obtain exclusive access to a regulator. |
1417 | * @dev: device for regulator "consumer" | 1340 | * @dev: device for regulator "consumer" |
1418 | * @id: Supply name or regulator ID. | 1341 | * @id: Supply name or regulator ID. |
@@ -1440,22 +1363,6 @@ struct regulator *regulator_get_exclusive(struct device *dev, const char *id) | |||
1440 | EXPORT_SYMBOL_GPL(regulator_get_exclusive); | 1363 | EXPORT_SYMBOL_GPL(regulator_get_exclusive); |
1441 | 1364 | ||
1442 | /** | 1365 | /** |
1443 | * devm_regulator_get_exclusive - Resource managed regulator_get_exclusive() | ||
1444 | * @dev: device for regulator "consumer" | ||
1445 | * @id: Supply name or regulator ID. | ||
1446 | * | ||
1447 | * Managed regulator_get_exclusive(). Regulators returned from this function | ||
1448 | * are automatically regulator_put() on driver detach. See regulator_get() for | ||
1449 | * more information. | ||
1450 | */ | ||
1451 | struct regulator *devm_regulator_get_exclusive(struct device *dev, | ||
1452 | const char *id) | ||
1453 | { | ||
1454 | return _devm_regulator_get(dev, id, EXCLUSIVE_GET); | ||
1455 | } | ||
1456 | EXPORT_SYMBOL_GPL(devm_regulator_get_exclusive); | ||
1457 | |||
1458 | /** | ||
1459 | * regulator_get_optional - obtain optional access to a regulator. | 1366 | * regulator_get_optional - obtain optional access to a regulator. |
1460 | * @dev: device for regulator "consumer" | 1367 | * @dev: device for regulator "consumer" |
1461 | * @id: Supply name or regulator ID. | 1368 | * @id: Supply name or regulator ID. |
@@ -1484,22 +1391,6 @@ struct regulator *regulator_get_optional(struct device *dev, const char *id) | |||
1484 | } | 1391 | } |
1485 | EXPORT_SYMBOL_GPL(regulator_get_optional); | 1392 | EXPORT_SYMBOL_GPL(regulator_get_optional); |
1486 | 1393 | ||
1487 | /** | ||
1488 | * devm_regulator_get_optional - Resource managed regulator_get_optional() | ||
1489 | * @dev: device for regulator "consumer" | ||
1490 | * @id: Supply name or regulator ID. | ||
1491 | * | ||
1492 | * Managed regulator_get_optional(). Regulators returned from this | ||
1493 | * function are automatically regulator_put() on driver detach. See | ||
1494 | * regulator_get_optional() for more information. | ||
1495 | */ | ||
1496 | struct regulator *devm_regulator_get_optional(struct device *dev, | ||
1497 | const char *id) | ||
1498 | { | ||
1499 | return _devm_regulator_get(dev, id, OPTIONAL_GET); | ||
1500 | } | ||
1501 | EXPORT_SYMBOL_GPL(devm_regulator_get_optional); | ||
1502 | |||
1503 | /* Locks held by regulator_put() */ | 1394 | /* Locks held by regulator_put() */ |
1504 | static void _regulator_put(struct regulator *regulator) | 1395 | static void _regulator_put(struct regulator *regulator) |
1505 | { | 1396 | { |
@@ -1541,35 +1432,6 @@ void regulator_put(struct regulator *regulator) | |||
1541 | } | 1432 | } |
1542 | EXPORT_SYMBOL_GPL(regulator_put); | 1433 | EXPORT_SYMBOL_GPL(regulator_put); |
1543 | 1434 | ||
1544 | static int devm_regulator_match(struct device *dev, void *res, void *data) | ||
1545 | { | ||
1546 | struct regulator **r = res; | ||
1547 | if (!r || !*r) { | ||
1548 | WARN_ON(!r || !*r); | ||
1549 | return 0; | ||
1550 | } | ||
1551 | return *r == data; | ||
1552 | } | ||
1553 | |||
1554 | /** | ||
1555 | * devm_regulator_put - Resource managed regulator_put() | ||
1556 | * @regulator: regulator to free | ||
1557 | * | ||
1558 | * Deallocate a regulator allocated with devm_regulator_get(). Normally | ||
1559 | * this function will not need to be called and the resource management | ||
1560 | * code will ensure that the resource is freed. | ||
1561 | */ | ||
1562 | void devm_regulator_put(struct regulator *regulator) | ||
1563 | { | ||
1564 | int rc; | ||
1565 | |||
1566 | rc = devres_release(regulator->dev, devm_regulator_release, | ||
1567 | devm_regulator_match, regulator); | ||
1568 | if (rc != 0) | ||
1569 | WARN_ON(rc); | ||
1570 | } | ||
1571 | EXPORT_SYMBOL_GPL(devm_regulator_put); | ||
1572 | |||
1573 | /* Manage enable GPIO list. Same GPIO pin can be shared among regulators */ | 1435 | /* Manage enable GPIO list. Same GPIO pin can be shared among regulators */ |
1574 | static int regulator_ena_gpio_request(struct regulator_dev *rdev, | 1436 | static int regulator_ena_gpio_request(struct regulator_dev *rdev, |
1575 | const struct regulator_config *config) | 1437 | const struct regulator_config *config) |
@@ -2909,52 +2771,6 @@ err: | |||
2909 | } | 2771 | } |
2910 | EXPORT_SYMBOL_GPL(regulator_bulk_get); | 2772 | EXPORT_SYMBOL_GPL(regulator_bulk_get); |
2911 | 2773 | ||
2912 | /** | ||
2913 | * devm_regulator_bulk_get - managed get multiple regulator consumers | ||
2914 | * | ||
2915 | * @dev: Device to supply | ||
2916 | * @num_consumers: Number of consumers to register | ||
2917 | * @consumers: Configuration of consumers; clients are stored here. | ||
2918 | * | ||
2919 | * @return 0 on success, an errno on failure. | ||
2920 | * | ||
2921 | * This helper function allows drivers to get several regulator | ||
2922 | * consumers in one operation with management, the regulators will | ||
2923 | * automatically be freed when the device is unbound. If any of the | ||
2924 | * regulators cannot be acquired then any regulators that were | ||
2925 | * allocated will be freed before returning to the caller. | ||
2926 | */ | ||
2927 | int devm_regulator_bulk_get(struct device *dev, int num_consumers, | ||
2928 | struct regulator_bulk_data *consumers) | ||
2929 | { | ||
2930 | int i; | ||
2931 | int ret; | ||
2932 | |||
2933 | for (i = 0; i < num_consumers; i++) | ||
2934 | consumers[i].consumer = NULL; | ||
2935 | |||
2936 | for (i = 0; i < num_consumers; i++) { | ||
2937 | consumers[i].consumer = devm_regulator_get(dev, | ||
2938 | consumers[i].supply); | ||
2939 | if (IS_ERR(consumers[i].consumer)) { | ||
2940 | ret = PTR_ERR(consumers[i].consumer); | ||
2941 | dev_err(dev, "Failed to get supply '%s': %d\n", | ||
2942 | consumers[i].supply, ret); | ||
2943 | consumers[i].consumer = NULL; | ||
2944 | goto err; | ||
2945 | } | ||
2946 | } | ||
2947 | |||
2948 | return 0; | ||
2949 | |||
2950 | err: | ||
2951 | for (i = 0; i < num_consumers && consumers[i].consumer; i++) | ||
2952 | devm_regulator_put(consumers[i].consumer); | ||
2953 | |||
2954 | return ret; | ||
2955 | } | ||
2956 | EXPORT_SYMBOL_GPL(devm_regulator_bulk_get); | ||
2957 | |||
2958 | static void regulator_bulk_enable_async(void *data, async_cookie_t cookie) | 2774 | static void regulator_bulk_enable_async(void *data, async_cookie_t cookie) |
2959 | { | 2775 | { |
2960 | struct regulator_bulk_data *bulk = data; | 2776 | struct regulator_bulk_data *bulk = data; |
@@ -3489,44 +3305,6 @@ clean: | |||
3489 | } | 3305 | } |
3490 | EXPORT_SYMBOL_GPL(regulator_register); | 3306 | EXPORT_SYMBOL_GPL(regulator_register); |
3491 | 3307 | ||
3492 | static void devm_rdev_release(struct device *dev, void *res) | ||
3493 | { | ||
3494 | regulator_unregister(*(struct regulator_dev **)res); | ||
3495 | } | ||
3496 | |||
3497 | /** | ||
3498 | * devm_regulator_register - Resource managed regulator_register() | ||
3499 | * @regulator_desc: regulator to register | ||
3500 | * @config: runtime configuration for regulator | ||
3501 | * | ||
3502 | * Called by regulator drivers to register a regulator. Returns a | ||
3503 | * valid pointer to struct regulator_dev on success or an ERR_PTR() on | ||
3504 | * error. The regulator will automatically be released when the device | ||
3505 | * is unbound. | ||
3506 | */ | ||
3507 | struct regulator_dev *devm_regulator_register(struct device *dev, | ||
3508 | const struct regulator_desc *regulator_desc, | ||
3509 | const struct regulator_config *config) | ||
3510 | { | ||
3511 | struct regulator_dev **ptr, *rdev; | ||
3512 | |||
3513 | ptr = devres_alloc(devm_rdev_release, sizeof(*ptr), | ||
3514 | GFP_KERNEL); | ||
3515 | if (!ptr) | ||
3516 | return ERR_PTR(-ENOMEM); | ||
3517 | |||
3518 | rdev = regulator_register(regulator_desc, config); | ||
3519 | if (!IS_ERR(rdev)) { | ||
3520 | *ptr = rdev; | ||
3521 | devres_add(dev, ptr); | ||
3522 | } else { | ||
3523 | devres_free(ptr); | ||
3524 | } | ||
3525 | |||
3526 | return rdev; | ||
3527 | } | ||
3528 | EXPORT_SYMBOL_GPL(devm_regulator_register); | ||
3529 | |||
3530 | /** | 3308 | /** |
3531 | * regulator_unregister - unregister regulator | 3309 | * regulator_unregister - unregister regulator |
3532 | * @rdev: regulator to unregister | 3310 | * @rdev: regulator to unregister |
@@ -3556,34 +3334,6 @@ void regulator_unregister(struct regulator_dev *rdev) | |||
3556 | } | 3334 | } |
3557 | EXPORT_SYMBOL_GPL(regulator_unregister); | 3335 | EXPORT_SYMBOL_GPL(regulator_unregister); |
3558 | 3336 | ||
3559 | static int devm_rdev_match(struct device *dev, void *res, void *data) | ||
3560 | { | ||
3561 | struct regulator_dev **r = res; | ||
3562 | if (!r || !*r) { | ||
3563 | WARN_ON(!r || !*r); | ||
3564 | return 0; | ||
3565 | } | ||
3566 | return *r == data; | ||
3567 | } | ||
3568 | |||
3569 | /** | ||
3570 | * devm_regulator_unregister - Resource managed regulator_unregister() | ||
3571 | * @regulator: regulator to free | ||
3572 | * | ||
3573 | * Unregister a regulator registered with devm_regulator_register(). | ||
3574 | * Normally this function will not need to be called and the resource | ||
3575 | * management code will ensure that the resource is freed. | ||
3576 | */ | ||
3577 | void devm_regulator_unregister(struct device *dev, struct regulator_dev *rdev) | ||
3578 | { | ||
3579 | int rc; | ||
3580 | |||
3581 | rc = devres_release(dev, devm_rdev_release, devm_rdev_match, rdev); | ||
3582 | if (rc != 0) | ||
3583 | WARN_ON(rc); | ||
3584 | } | ||
3585 | EXPORT_SYMBOL_GPL(devm_regulator_unregister); | ||
3586 | |||
3587 | /** | 3337 | /** |
3588 | * regulator_suspend_prepare - prepare regulators for system wide suspend | 3338 | * regulator_suspend_prepare - prepare regulators for system wide suspend |
3589 | * @state: system suspend state | 3339 | * @state: system suspend state |
diff --git a/drivers/regulator/devres.c b/drivers/regulator/devres.c new file mode 100644 index 000000000000..2672a029fa25 --- /dev/null +++ b/drivers/regulator/devres.c | |||
@@ -0,0 +1,252 @@ | |||
1 | /* | ||
2 | * devres.c -- Voltage/Current Regulator framework devres implementation. | ||
3 | * | ||
4 | * Copyright 2013 Linaro Ltd | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify it | ||
7 | * under the terms of the GNU General Public License as published by the | ||
8 | * Free Software Foundation; either version 2 of the License, or (at your | ||
9 | * option) any later version. | ||
10 | * | ||
11 | */ | ||
12 | |||
13 | #include <linux/kernel.h> | ||
14 | #include <linux/err.h> | ||
15 | #include <linux/regmap.h> | ||
16 | #include <linux/regulator/consumer.h> | ||
17 | #include <linux/regulator/driver.h> | ||
18 | #include <linux/module.h> | ||
19 | |||
20 | #include "internal.h" | ||
21 | |||
22 | enum { | ||
23 | NORMAL_GET, | ||
24 | EXCLUSIVE_GET, | ||
25 | OPTIONAL_GET, | ||
26 | }; | ||
27 | |||
28 | static void devm_regulator_release(struct device *dev, void *res) | ||
29 | { | ||
30 | regulator_put(*(struct regulator **)res); | ||
31 | } | ||
32 | |||
33 | static struct regulator *_devm_regulator_get(struct device *dev, const char *id, | ||
34 | int get_type) | ||
35 | { | ||
36 | struct regulator **ptr, *regulator; | ||
37 | |||
38 | ptr = devres_alloc(devm_regulator_release, sizeof(*ptr), GFP_KERNEL); | ||
39 | if (!ptr) | ||
40 | return ERR_PTR(-ENOMEM); | ||
41 | |||
42 | switch (get_type) { | ||
43 | case NORMAL_GET: | ||
44 | regulator = regulator_get(dev, id); | ||
45 | break; | ||
46 | case EXCLUSIVE_GET: | ||
47 | regulator = regulator_get_exclusive(dev, id); | ||
48 | break; | ||
49 | case OPTIONAL_GET: | ||
50 | regulator = regulator_get_optional(dev, id); | ||
51 | break; | ||
52 | default: | ||
53 | regulator = ERR_PTR(-EINVAL); | ||
54 | } | ||
55 | |||
56 | if (!IS_ERR(regulator)) { | ||
57 | *ptr = regulator; | ||
58 | devres_add(dev, ptr); | ||
59 | } else { | ||
60 | devres_free(ptr); | ||
61 | } | ||
62 | |||
63 | return regulator; | ||
64 | } | ||
65 | |||
66 | /** | ||
67 | * devm_regulator_get - Resource managed regulator_get() | ||
68 | * @dev: device for regulator "consumer" | ||
69 | * @id: Supply name or regulator ID. | ||
70 | * | ||
71 | * Managed regulator_get(). Regulators returned from this function are | ||
72 | * automatically regulator_put() on driver detach. See regulator_get() for more | ||
73 | * information. | ||
74 | */ | ||
75 | struct regulator *devm_regulator_get(struct device *dev, const char *id) | ||
76 | { | ||
77 | return _devm_regulator_get(dev, id, NORMAL_GET); | ||
78 | } | ||
79 | EXPORT_SYMBOL_GPL(devm_regulator_get); | ||
80 | |||
81 | /** | ||
82 | * devm_regulator_get_exclusive - Resource managed regulator_get_exclusive() | ||
83 | * @dev: device for regulator "consumer" | ||
84 | * @id: Supply name or regulator ID. | ||
85 | * | ||
86 | * Managed regulator_get_exclusive(). Regulators returned from this function | ||
87 | * are automatically regulator_put() on driver detach. See regulator_get() for | ||
88 | * more information. | ||
89 | */ | ||
90 | struct regulator *devm_regulator_get_exclusive(struct device *dev, | ||
91 | const char *id) | ||
92 | { | ||
93 | return _devm_regulator_get(dev, id, EXCLUSIVE_GET); | ||
94 | } | ||
95 | EXPORT_SYMBOL_GPL(devm_regulator_get_exclusive); | ||
96 | |||
97 | /** | ||
98 | * devm_regulator_get_optional - Resource managed regulator_get_optional() | ||
99 | * @dev: device for regulator "consumer" | ||
100 | * @id: Supply name or regulator ID. | ||
101 | * | ||
102 | * Managed regulator_get_optional(). Regulators returned from this | ||
103 | * function are automatically regulator_put() on driver detach. See | ||
104 | * regulator_get_optional() for more information. | ||
105 | */ | ||
106 | struct regulator *devm_regulator_get_optional(struct device *dev, | ||
107 | const char *id) | ||
108 | { | ||
109 | return _devm_regulator_get(dev, id, OPTIONAL_GET); | ||
110 | } | ||
111 | EXPORT_SYMBOL_GPL(devm_regulator_get_optional); | ||
112 | |||
113 | static int devm_regulator_match(struct device *dev, void *res, void *data) | ||
114 | { | ||
115 | struct regulator **r = res; | ||
116 | if (!r || !*r) { | ||
117 | WARN_ON(!r || !*r); | ||
118 | return 0; | ||
119 | } | ||
120 | return *r == data; | ||
121 | } | ||
122 | |||
123 | /** | ||
124 | * devm_regulator_put - Resource managed regulator_put() | ||
125 | * @regulator: regulator to free | ||
126 | * | ||
127 | * Deallocate a regulator allocated with devm_regulator_get(). Normally | ||
128 | * this function will not need to be called and the resource management | ||
129 | * code will ensure that the resource is freed. | ||
130 | */ | ||
131 | void devm_regulator_put(struct regulator *regulator) | ||
132 | { | ||
133 | int rc; | ||
134 | |||
135 | rc = devres_release(regulator->dev, devm_regulator_release, | ||
136 | devm_regulator_match, regulator); | ||
137 | if (rc != 0) | ||
138 | WARN_ON(rc); | ||
139 | } | ||
140 | EXPORT_SYMBOL_GPL(devm_regulator_put); | ||
141 | |||
142 | /** | ||
143 | * devm_regulator_bulk_get - managed get multiple regulator consumers | ||
144 | * | ||
145 | * @dev: Device to supply | ||
146 | * @num_consumers: Number of consumers to register | ||
147 | * @consumers: Configuration of consumers; clients are stored here. | ||
148 | * | ||
149 | * @return 0 on success, an errno on failure. | ||
150 | * | ||
151 | * This helper function allows drivers to get several regulator | ||
152 | * consumers in one operation with management, the regulators will | ||
153 | * automatically be freed when the device is unbound. If any of the | ||
154 | * regulators cannot be acquired then any regulators that were | ||
155 | * allocated will be freed before returning to the caller. | ||
156 | */ | ||
157 | int devm_regulator_bulk_get(struct device *dev, int num_consumers, | ||
158 | struct regulator_bulk_data *consumers) | ||
159 | { | ||
160 | int i; | ||
161 | int ret; | ||
162 | |||
163 | for (i = 0; i < num_consumers; i++) | ||
164 | consumers[i].consumer = NULL; | ||
165 | |||
166 | for (i = 0; i < num_consumers; i++) { | ||
167 | consumers[i].consumer = devm_regulator_get(dev, | ||
168 | consumers[i].supply); | ||
169 | if (IS_ERR(consumers[i].consumer)) { | ||
170 | ret = PTR_ERR(consumers[i].consumer); | ||
171 | dev_err(dev, "Failed to get supply '%s': %d\n", | ||
172 | consumers[i].supply, ret); | ||
173 | consumers[i].consumer = NULL; | ||
174 | goto err; | ||
175 | } | ||
176 | } | ||
177 | |||
178 | return 0; | ||
179 | |||
180 | err: | ||
181 | for (i = 0; i < num_consumers && consumers[i].consumer; i++) | ||
182 | devm_regulator_put(consumers[i].consumer); | ||
183 | |||
184 | return ret; | ||
185 | } | ||
186 | EXPORT_SYMBOL_GPL(devm_regulator_bulk_get); | ||
187 | |||
188 | static void devm_rdev_release(struct device *dev, void *res) | ||
189 | { | ||
190 | regulator_unregister(*(struct regulator_dev **)res); | ||
191 | } | ||
192 | |||
193 | /** | ||
194 | * devm_regulator_register - Resource managed regulator_register() | ||
195 | * @regulator_desc: regulator to register | ||
196 | * @config: runtime configuration for regulator | ||
197 | * | ||
198 | * Called by regulator drivers to register a regulator. Returns a | ||
199 | * valid pointer to struct regulator_dev on success or an ERR_PTR() on | ||
200 | * error. The regulator will automatically be released when the device | ||
201 | * is unbound. | ||
202 | */ | ||
203 | struct regulator_dev *devm_regulator_register(struct device *dev, | ||
204 | const struct regulator_desc *regulator_desc, | ||
205 | const struct regulator_config *config) | ||
206 | { | ||
207 | struct regulator_dev **ptr, *rdev; | ||
208 | |||
209 | ptr = devres_alloc(devm_rdev_release, sizeof(*ptr), | ||
210 | GFP_KERNEL); | ||
211 | if (!ptr) | ||
212 | return ERR_PTR(-ENOMEM); | ||
213 | |||
214 | rdev = regulator_register(regulator_desc, config); | ||
215 | if (!IS_ERR(rdev)) { | ||
216 | *ptr = rdev; | ||
217 | devres_add(dev, ptr); | ||
218 | } else { | ||
219 | devres_free(ptr); | ||
220 | } | ||
221 | |||
222 | return rdev; | ||
223 | } | ||
224 | EXPORT_SYMBOL_GPL(devm_regulator_register); | ||
225 | |||
226 | static int devm_rdev_match(struct device *dev, void *res, void *data) | ||
227 | { | ||
228 | struct regulator_dev **r = res; | ||
229 | if (!r || !*r) { | ||
230 | WARN_ON(!r || !*r); | ||
231 | return 0; | ||
232 | } | ||
233 | return *r == data; | ||
234 | } | ||
235 | |||
236 | /** | ||
237 | * devm_regulator_unregister - Resource managed regulator_unregister() | ||
238 | * @regulator: regulator to free | ||
239 | * | ||
240 | * Unregister a regulator registered with devm_regulator_register(). | ||
241 | * Normally this function will not need to be called and the resource | ||
242 | * management code will ensure that the resource is freed. | ||
243 | */ | ||
244 | void devm_regulator_unregister(struct device *dev, struct regulator_dev *rdev) | ||
245 | { | ||
246 | int rc; | ||
247 | |||
248 | rc = devres_release(dev, devm_rdev_release, devm_rdev_match, rdev); | ||
249 | if (rc != 0) | ||
250 | WARN_ON(rc); | ||
251 | } | ||
252 | EXPORT_SYMBOL_GPL(devm_regulator_unregister); | ||
diff --git a/drivers/regulator/internal.h b/drivers/regulator/internal.h new file mode 100644 index 000000000000..84bbda10c396 --- /dev/null +++ b/drivers/regulator/internal.h | |||
@@ -0,0 +1,38 @@ | |||
1 | /* | ||
2 | * internal.h -- Voltage/Current Regulator framework internal code | ||
3 | * | ||
4 | * Copyright 2007, 2008 Wolfson Microelectronics PLC. | ||
5 | * Copyright 2008 SlimLogic Ltd. | ||
6 | * | ||
7 | * Author: Liam Girdwood <lrg@slimlogic.co.uk> | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify it | ||
10 | * under the terms of the GNU General Public License as published by the | ||
11 | * Free Software Foundation; either version 2 of the License, or (at your | ||
12 | * option) any later version. | ||
13 | * | ||
14 | */ | ||
15 | |||
16 | #ifndef __REGULATOR_INTERNAL_H | ||
17 | #define __REGULATOR_INTERNAL_H | ||
18 | |||
19 | /* | ||
20 | * struct regulator | ||
21 | * | ||
22 | * One for each consumer device. | ||
23 | */ | ||
24 | struct regulator { | ||
25 | struct device *dev; | ||
26 | struct list_head list; | ||
27 | unsigned int always_on:1; | ||
28 | unsigned int bypass:1; | ||
29 | int uA_load; | ||
30 | int min_uV; | ||
31 | int max_uV; | ||
32 | char *supply_name; | ||
33 | struct device_attribute dev_attr; | ||
34 | struct regulator_dev *rdev; | ||
35 | struct dentry *debugfs; | ||
36 | }; | ||
37 | |||
38 | #endif | ||