diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2011-08-01 20:05:46 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2011-08-01 20:05:46 -0400 |
commit | cfe22345ad5ef29e192e157fdc3e17d357e4bc24 (patch) | |
tree | 15173bab84cb9122a95d46f2b49fb139362b5248 /drivers/regulator | |
parent | 60ad4466821a96913a9b567115e194ed1087c2d7 (diff) | |
parent | 424c3d4a2c7d4ac3467a4849f8ccc230f670c35a (diff) |
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/lrg/voltage-2.6
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/lrg/voltage-2.6: (23 commits)
regulator: Improve WM831x DVS VSEL selection algorithm
regulator: Bootstrap wm831x DVS VSEL value from ON VSEL if not already set
regulator: Set up GPIO for WM831x VSEL before enabling VSEL mode
regulator: Add EPEs to the MODULE_ALIAS() for wm831x-dcdc
regulator: Fix WM831x DCDC DVS VSEL bootstrapping
regulator: Fix WM831x regulator ID lookups for multiple WM831xs
regulator: Fix argument format type errors in error prints
regulator: Fix memory leak in set_machine_constraints() error paths
regulator: Make core more chatty about some errors
regulator: tps65910: Fix array access out of bounds bug
regulator: tps65910: Add missing breaks in switch/case
regulator: tps65910: Fix a memory leak in tps65910_probe error path
regulator: TWL: Remove entry of RES_ID for 6030 macros
ASoC: tlv320aic3x: Add correct hw registers to Line1 cross connect muxes
regulator: Add basic per consumer debugfs
regulator: Add rdev_crit() macro
regulator: Refactor supply implementation to work as regular consumers
regulator: Include the device name in the microamps_requested_ file
regulator: Increase the limit on sysfs file names
regulator: Properly register dummy regulator driver
...
Diffstat (limited to 'drivers/regulator')
-rw-r--r-- | drivers/regulator/core.c | 190 | ||||
-rw-r--r-- | drivers/regulator/dummy.c | 32 | ||||
-rw-r--r-- | drivers/regulator/tps65910-regulator.c | 63 | ||||
-rw-r--r-- | drivers/regulator/twl-regulator.c | 66 | ||||
-rw-r--r-- | drivers/regulator/wm831x-dcdc.c | 126 | ||||
-rw-r--r-- | drivers/regulator/wm831x-ldo.c | 25 | ||||
-rw-r--r-- | drivers/regulator/wm8994-regulator.c | 4 |
7 files changed, 307 insertions, 199 deletions
diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index d3e38790906e..d8e6a429e8ba 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c | |||
@@ -20,6 +20,7 @@ | |||
20 | #include <linux/debugfs.h> | 20 | #include <linux/debugfs.h> |
21 | #include <linux/device.h> | 21 | #include <linux/device.h> |
22 | #include <linux/slab.h> | 22 | #include <linux/slab.h> |
23 | #include <linux/async.h> | ||
23 | #include <linux/err.h> | 24 | #include <linux/err.h> |
24 | #include <linux/mutex.h> | 25 | #include <linux/mutex.h> |
25 | #include <linux/suspend.h> | 26 | #include <linux/suspend.h> |
@@ -33,6 +34,8 @@ | |||
33 | 34 | ||
34 | #include "dummy.h" | 35 | #include "dummy.h" |
35 | 36 | ||
37 | #define rdev_crit(rdev, fmt, ...) \ | ||
38 | pr_crit("%s: " fmt, rdev_get_name(rdev), ##__VA_ARGS__) | ||
36 | #define rdev_err(rdev, fmt, ...) \ | 39 | #define rdev_err(rdev, fmt, ...) \ |
37 | pr_err("%s: " fmt, rdev_get_name(rdev), ##__VA_ARGS__) | 40 | pr_err("%s: " fmt, rdev_get_name(rdev), ##__VA_ARGS__) |
38 | #define rdev_warn(rdev, fmt, ...) \ | 41 | #define rdev_warn(rdev, fmt, ...) \ |
@@ -78,11 +81,13 @@ struct regulator { | |||
78 | char *supply_name; | 81 | char *supply_name; |
79 | struct device_attribute dev_attr; | 82 | struct device_attribute dev_attr; |
80 | struct regulator_dev *rdev; | 83 | struct regulator_dev *rdev; |
84 | #ifdef CONFIG_DEBUG_FS | ||
85 | struct dentry *debugfs; | ||
86 | #endif | ||
81 | }; | 87 | }; |
82 | 88 | ||
83 | static int _regulator_is_enabled(struct regulator_dev *rdev); | 89 | static int _regulator_is_enabled(struct regulator_dev *rdev); |
84 | static int _regulator_disable(struct regulator_dev *rdev, | 90 | static int _regulator_disable(struct regulator_dev *rdev); |
85 | struct regulator_dev **supply_rdev_ptr); | ||
86 | static int _regulator_get_voltage(struct regulator_dev *rdev); | 91 | static int _regulator_get_voltage(struct regulator_dev *rdev); |
87 | static int _regulator_get_current_limit(struct regulator_dev *rdev); | 92 | static int _regulator_get_current_limit(struct regulator_dev *rdev); |
88 | static unsigned int _regulator_get_mode(struct regulator_dev *rdev); | 93 | static unsigned int _regulator_get_mode(struct regulator_dev *rdev); |
@@ -90,6 +95,9 @@ static void _notifier_call_chain(struct regulator_dev *rdev, | |||
90 | unsigned long event, void *data); | 95 | unsigned long event, void *data); |
91 | static int _regulator_do_set_voltage(struct regulator_dev *rdev, | 96 | static int _regulator_do_set_voltage(struct regulator_dev *rdev, |
92 | int min_uV, int max_uV); | 97 | int min_uV, int max_uV); |
98 | static struct regulator *create_regulator(struct regulator_dev *rdev, | ||
99 | struct device *dev, | ||
100 | const char *supply_name); | ||
93 | 101 | ||
94 | static const char *rdev_get_name(struct regulator_dev *rdev) | 102 | static const char *rdev_get_name(struct regulator_dev *rdev) |
95 | { | 103 | { |
@@ -143,8 +151,11 @@ static int regulator_check_voltage(struct regulator_dev *rdev, | |||
143 | if (*min_uV < rdev->constraints->min_uV) | 151 | if (*min_uV < rdev->constraints->min_uV) |
144 | *min_uV = rdev->constraints->min_uV; | 152 | *min_uV = rdev->constraints->min_uV; |
145 | 153 | ||
146 | if (*min_uV > *max_uV) | 154 | if (*min_uV > *max_uV) { |
155 | rdev_err(rdev, "unsupportable voltage range: %d-%duV\n", | ||
156 | *min_uV, *max_uV); | ||
147 | return -EINVAL; | 157 | return -EINVAL; |
158 | } | ||
148 | 159 | ||
149 | return 0; | 160 | return 0; |
150 | } | 161 | } |
@@ -197,8 +208,11 @@ static int regulator_check_current_limit(struct regulator_dev *rdev, | |||
197 | if (*min_uA < rdev->constraints->min_uA) | 208 | if (*min_uA < rdev->constraints->min_uA) |
198 | *min_uA = rdev->constraints->min_uA; | 209 | *min_uA = rdev->constraints->min_uA; |
199 | 210 | ||
200 | if (*min_uA > *max_uA) | 211 | if (*min_uA > *max_uA) { |
212 | rdev_err(rdev, "unsupportable current range: %d-%duA\n", | ||
213 | *min_uA, *max_uA); | ||
201 | return -EINVAL; | 214 | return -EINVAL; |
215 | } | ||
202 | 216 | ||
203 | return 0; | 217 | return 0; |
204 | } | 218 | } |
@@ -213,6 +227,7 @@ static int regulator_mode_constrain(struct regulator_dev *rdev, int *mode) | |||
213 | case REGULATOR_MODE_STANDBY: | 227 | case REGULATOR_MODE_STANDBY: |
214 | break; | 228 | break; |
215 | default: | 229 | default: |
230 | rdev_err(rdev, "invalid mode %x specified\n", *mode); | ||
216 | return -EINVAL; | 231 | return -EINVAL; |
217 | } | 232 | } |
218 | 233 | ||
@@ -779,7 +794,6 @@ static int machine_constraints_voltage(struct regulator_dev *rdev, | |||
779 | if (ret < 0) { | 794 | if (ret < 0) { |
780 | rdev_err(rdev, "failed to apply %duV constraint\n", | 795 | rdev_err(rdev, "failed to apply %duV constraint\n", |
781 | rdev->constraints->min_uV); | 796 | rdev->constraints->min_uV); |
782 | rdev->constraints = NULL; | ||
783 | return ret; | 797 | return ret; |
784 | } | 798 | } |
785 | } | 799 | } |
@@ -882,7 +896,6 @@ static int set_machine_constraints(struct regulator_dev *rdev, | |||
882 | ret = suspend_prepare(rdev, rdev->constraints->initial_state); | 896 | ret = suspend_prepare(rdev, rdev->constraints->initial_state); |
883 | if (ret < 0) { | 897 | if (ret < 0) { |
884 | rdev_err(rdev, "failed to set suspend state\n"); | 898 | rdev_err(rdev, "failed to set suspend state\n"); |
885 | rdev->constraints = NULL; | ||
886 | goto out; | 899 | goto out; |
887 | } | 900 | } |
888 | } | 901 | } |
@@ -909,13 +922,15 @@ static int set_machine_constraints(struct regulator_dev *rdev, | |||
909 | ret = ops->enable(rdev); | 922 | ret = ops->enable(rdev); |
910 | if (ret < 0) { | 923 | if (ret < 0) { |
911 | rdev_err(rdev, "failed to enable\n"); | 924 | rdev_err(rdev, "failed to enable\n"); |
912 | rdev->constraints = NULL; | ||
913 | goto out; | 925 | goto out; |
914 | } | 926 | } |
915 | } | 927 | } |
916 | 928 | ||
917 | print_constraints(rdev); | 929 | print_constraints(rdev); |
930 | return 0; | ||
918 | out: | 931 | out: |
932 | kfree(rdev->constraints); | ||
933 | rdev->constraints = NULL; | ||
919 | return ret; | 934 | return ret; |
920 | } | 935 | } |
921 | 936 | ||
@@ -929,21 +944,20 @@ out: | |||
929 | * core if it's child is enabled. | 944 | * core if it's child is enabled. |
930 | */ | 945 | */ |
931 | static int set_supply(struct regulator_dev *rdev, | 946 | static int set_supply(struct regulator_dev *rdev, |
932 | struct regulator_dev *supply_rdev) | 947 | struct regulator_dev *supply_rdev) |
933 | { | 948 | { |
934 | int err; | 949 | int err; |
935 | 950 | ||
936 | err = sysfs_create_link(&rdev->dev.kobj, &supply_rdev->dev.kobj, | 951 | rdev_info(rdev, "supplied by %s\n", rdev_get_name(supply_rdev)); |
937 | "supply"); | 952 | |
938 | if (err) { | 953 | rdev->supply = create_regulator(supply_rdev, &rdev->dev, "SUPPLY"); |
939 | rdev_err(rdev, "could not add device link %s err %d\n", | 954 | if (IS_ERR(rdev->supply)) { |
940 | supply_rdev->dev.kobj.name, err); | 955 | err = PTR_ERR(rdev->supply); |
941 | goto out; | 956 | rdev->supply = NULL; |
957 | return err; | ||
942 | } | 958 | } |
943 | rdev->supply = supply_rdev; | 959 | |
944 | list_add(&rdev->slist, &supply_rdev->supply_list); | 960 | return 0; |
945 | out: | ||
946 | return err; | ||
947 | } | 961 | } |
948 | 962 | ||
949 | /** | 963 | /** |
@@ -1032,7 +1046,7 @@ static void unset_regulator_supplies(struct regulator_dev *rdev) | |||
1032 | } | 1046 | } |
1033 | } | 1047 | } |
1034 | 1048 | ||
1035 | #define REG_STR_SIZE 32 | 1049 | #define REG_STR_SIZE 64 |
1036 | 1050 | ||
1037 | static struct regulator *create_regulator(struct regulator_dev *rdev, | 1051 | static struct regulator *create_regulator(struct regulator_dev *rdev, |
1038 | struct device *dev, | 1052 | struct device *dev, |
@@ -1052,8 +1066,9 @@ static struct regulator *create_regulator(struct regulator_dev *rdev, | |||
1052 | 1066 | ||
1053 | if (dev) { | 1067 | if (dev) { |
1054 | /* create a 'requested_microamps_name' sysfs entry */ | 1068 | /* create a 'requested_microamps_name' sysfs entry */ |
1055 | size = scnprintf(buf, REG_STR_SIZE, "microamps_requested_%s", | 1069 | size = scnprintf(buf, REG_STR_SIZE, |
1056 | supply_name); | 1070 | "microamps_requested_%s-%s", |
1071 | dev_name(dev), supply_name); | ||
1057 | if (size >= REG_STR_SIZE) | 1072 | if (size >= REG_STR_SIZE) |
1058 | goto overflow_err; | 1073 | goto overflow_err; |
1059 | 1074 | ||
@@ -1088,7 +1103,28 @@ static struct regulator *create_regulator(struct regulator_dev *rdev, | |||
1088 | dev->kobj.name, err); | 1103 | dev->kobj.name, err); |
1089 | goto link_name_err; | 1104 | goto link_name_err; |
1090 | } | 1105 | } |
1106 | } else { | ||
1107 | regulator->supply_name = kstrdup(supply_name, GFP_KERNEL); | ||
1108 | if (regulator->supply_name == NULL) | ||
1109 | goto attr_err; | ||
1110 | } | ||
1111 | |||
1112 | #ifdef CONFIG_DEBUG_FS | ||
1113 | regulator->debugfs = debugfs_create_dir(regulator->supply_name, | ||
1114 | rdev->debugfs); | ||
1115 | if (IS_ERR_OR_NULL(regulator->debugfs)) { | ||
1116 | rdev_warn(rdev, "Failed to create debugfs directory\n"); | ||
1117 | regulator->debugfs = NULL; | ||
1118 | } else { | ||
1119 | debugfs_create_u32("uA_load", 0444, regulator->debugfs, | ||
1120 | ®ulator->uA_load); | ||
1121 | debugfs_create_u32("min_uV", 0444, regulator->debugfs, | ||
1122 | ®ulator->min_uV); | ||
1123 | debugfs_create_u32("max_uV", 0444, regulator->debugfs, | ||
1124 | ®ulator->max_uV); | ||
1091 | } | 1125 | } |
1126 | #endif | ||
1127 | |||
1092 | mutex_unlock(&rdev->mutex); | 1128 | mutex_unlock(&rdev->mutex); |
1093 | return regulator; | 1129 | return regulator; |
1094 | link_name_err: | 1130 | link_name_err: |
@@ -1267,13 +1303,17 @@ void regulator_put(struct regulator *regulator) | |||
1267 | mutex_lock(®ulator_list_mutex); | 1303 | mutex_lock(®ulator_list_mutex); |
1268 | rdev = regulator->rdev; | 1304 | rdev = regulator->rdev; |
1269 | 1305 | ||
1306 | #ifdef CONFIG_DEBUG_FS | ||
1307 | debugfs_remove_recursive(regulator->debugfs); | ||
1308 | #endif | ||
1309 | |||
1270 | /* remove any sysfs entries */ | 1310 | /* remove any sysfs entries */ |
1271 | if (regulator->dev) { | 1311 | if (regulator->dev) { |
1272 | sysfs_remove_link(&rdev->dev.kobj, regulator->supply_name); | 1312 | sysfs_remove_link(&rdev->dev.kobj, regulator->supply_name); |
1273 | kfree(regulator->supply_name); | ||
1274 | device_remove_file(regulator->dev, ®ulator->dev_attr); | 1313 | device_remove_file(regulator->dev, ®ulator->dev_attr); |
1275 | kfree(regulator->dev_attr.attr.name); | 1314 | kfree(regulator->dev_attr.attr.name); |
1276 | } | 1315 | } |
1316 | kfree(regulator->supply_name); | ||
1277 | list_del(®ulator->list); | 1317 | list_del(®ulator->list); |
1278 | kfree(regulator); | 1318 | kfree(regulator); |
1279 | 1319 | ||
@@ -1301,19 +1341,6 @@ static int _regulator_enable(struct regulator_dev *rdev) | |||
1301 | { | 1341 | { |
1302 | int ret, delay; | 1342 | int ret, delay; |
1303 | 1343 | ||
1304 | if (rdev->use_count == 0) { | ||
1305 | /* do we need to enable the supply regulator first */ | ||
1306 | if (rdev->supply) { | ||
1307 | mutex_lock(&rdev->supply->mutex); | ||
1308 | ret = _regulator_enable(rdev->supply); | ||
1309 | mutex_unlock(&rdev->supply->mutex); | ||
1310 | if (ret < 0) { | ||
1311 | rdev_err(rdev, "failed to enable: %d\n", ret); | ||
1312 | return ret; | ||
1313 | } | ||
1314 | } | ||
1315 | } | ||
1316 | |||
1317 | /* check voltage and requested load before enabling */ | 1344 | /* check voltage and requested load before enabling */ |
1318 | if (rdev->constraints && | 1345 | if (rdev->constraints && |
1319 | (rdev->constraints->valid_ops_mask & REGULATOR_CHANGE_DRMS)) | 1346 | (rdev->constraints->valid_ops_mask & REGULATOR_CHANGE_DRMS)) |
@@ -1388,19 +1415,27 @@ int regulator_enable(struct regulator *regulator) | |||
1388 | struct regulator_dev *rdev = regulator->rdev; | 1415 | struct regulator_dev *rdev = regulator->rdev; |
1389 | int ret = 0; | 1416 | int ret = 0; |
1390 | 1417 | ||
1418 | if (rdev->supply) { | ||
1419 | ret = regulator_enable(rdev->supply); | ||
1420 | if (ret != 0) | ||
1421 | return ret; | ||
1422 | } | ||
1423 | |||
1391 | mutex_lock(&rdev->mutex); | 1424 | mutex_lock(&rdev->mutex); |
1392 | ret = _regulator_enable(rdev); | 1425 | ret = _regulator_enable(rdev); |
1393 | mutex_unlock(&rdev->mutex); | 1426 | mutex_unlock(&rdev->mutex); |
1427 | |||
1428 | if (ret != 0) | ||
1429 | regulator_disable(rdev->supply); | ||
1430 | |||
1394 | return ret; | 1431 | return ret; |
1395 | } | 1432 | } |
1396 | EXPORT_SYMBOL_GPL(regulator_enable); | 1433 | EXPORT_SYMBOL_GPL(regulator_enable); |
1397 | 1434 | ||
1398 | /* locks held by regulator_disable() */ | 1435 | /* locks held by regulator_disable() */ |
1399 | static int _regulator_disable(struct regulator_dev *rdev, | 1436 | static int _regulator_disable(struct regulator_dev *rdev) |
1400 | struct regulator_dev **supply_rdev_ptr) | ||
1401 | { | 1437 | { |
1402 | int ret = 0; | 1438 | int ret = 0; |
1403 | *supply_rdev_ptr = NULL; | ||
1404 | 1439 | ||
1405 | if (WARN(rdev->use_count <= 0, | 1440 | if (WARN(rdev->use_count <= 0, |
1406 | "unbalanced disables for %s\n", rdev_get_name(rdev))) | 1441 | "unbalanced disables for %s\n", rdev_get_name(rdev))) |
@@ -1427,9 +1462,6 @@ static int _regulator_disable(struct regulator_dev *rdev, | |||
1427 | NULL); | 1462 | NULL); |
1428 | } | 1463 | } |
1429 | 1464 | ||
1430 | /* decrease our supplies ref count and disable if required */ | ||
1431 | *supply_rdev_ptr = rdev->supply; | ||
1432 | |||
1433 | rdev->use_count = 0; | 1465 | rdev->use_count = 0; |
1434 | } else if (rdev->use_count > 1) { | 1466 | } else if (rdev->use_count > 1) { |
1435 | 1467 | ||
@@ -1440,6 +1472,7 @@ static int _regulator_disable(struct regulator_dev *rdev, | |||
1440 | 1472 | ||
1441 | rdev->use_count--; | 1473 | rdev->use_count--; |
1442 | } | 1474 | } |
1475 | |||
1443 | return ret; | 1476 | return ret; |
1444 | } | 1477 | } |
1445 | 1478 | ||
@@ -1458,29 +1491,21 @@ static int _regulator_disable(struct regulator_dev *rdev, | |||
1458 | int regulator_disable(struct regulator *regulator) | 1491 | int regulator_disable(struct regulator *regulator) |
1459 | { | 1492 | { |
1460 | struct regulator_dev *rdev = regulator->rdev; | 1493 | struct regulator_dev *rdev = regulator->rdev; |
1461 | struct regulator_dev *supply_rdev = NULL; | ||
1462 | int ret = 0; | 1494 | int ret = 0; |
1463 | 1495 | ||
1464 | mutex_lock(&rdev->mutex); | 1496 | mutex_lock(&rdev->mutex); |
1465 | ret = _regulator_disable(rdev, &supply_rdev); | 1497 | ret = _regulator_disable(rdev); |
1466 | mutex_unlock(&rdev->mutex); | 1498 | mutex_unlock(&rdev->mutex); |
1467 | 1499 | ||
1468 | /* decrease our supplies ref count and disable if required */ | 1500 | if (ret == 0 && rdev->supply) |
1469 | while (supply_rdev != NULL) { | 1501 | regulator_disable(rdev->supply); |
1470 | rdev = supply_rdev; | ||
1471 | |||
1472 | mutex_lock(&rdev->mutex); | ||
1473 | _regulator_disable(rdev, &supply_rdev); | ||
1474 | mutex_unlock(&rdev->mutex); | ||
1475 | } | ||
1476 | 1502 | ||
1477 | return ret; | 1503 | return ret; |
1478 | } | 1504 | } |
1479 | EXPORT_SYMBOL_GPL(regulator_disable); | 1505 | EXPORT_SYMBOL_GPL(regulator_disable); |
1480 | 1506 | ||
1481 | /* locks held by regulator_force_disable() */ | 1507 | /* locks held by regulator_force_disable() */ |
1482 | static int _regulator_force_disable(struct regulator_dev *rdev, | 1508 | static int _regulator_force_disable(struct regulator_dev *rdev) |
1483 | struct regulator_dev **supply_rdev_ptr) | ||
1484 | { | 1509 | { |
1485 | int ret = 0; | 1510 | int ret = 0; |
1486 | 1511 | ||
@@ -1497,10 +1522,6 @@ static int _regulator_force_disable(struct regulator_dev *rdev, | |||
1497 | REGULATOR_EVENT_DISABLE, NULL); | 1522 | REGULATOR_EVENT_DISABLE, NULL); |
1498 | } | 1523 | } |
1499 | 1524 | ||
1500 | /* decrease our supplies ref count and disable if required */ | ||
1501 | *supply_rdev_ptr = rdev->supply; | ||
1502 | |||
1503 | rdev->use_count = 0; | ||
1504 | return ret; | 1525 | return ret; |
1505 | } | 1526 | } |
1506 | 1527 | ||
@@ -1516,16 +1537,16 @@ static int _regulator_force_disable(struct regulator_dev *rdev, | |||
1516 | int regulator_force_disable(struct regulator *regulator) | 1537 | int regulator_force_disable(struct regulator *regulator) |
1517 | { | 1538 | { |
1518 | struct regulator_dev *rdev = regulator->rdev; | 1539 | struct regulator_dev *rdev = regulator->rdev; |
1519 | struct regulator_dev *supply_rdev = NULL; | ||
1520 | int ret; | 1540 | int ret; |
1521 | 1541 | ||
1522 | mutex_lock(&rdev->mutex); | 1542 | mutex_lock(&rdev->mutex); |
1523 | regulator->uA_load = 0; | 1543 | regulator->uA_load = 0; |
1524 | ret = _regulator_force_disable(rdev, &supply_rdev); | 1544 | ret = _regulator_force_disable(regulator->rdev); |
1525 | mutex_unlock(&rdev->mutex); | 1545 | mutex_unlock(&rdev->mutex); |
1526 | 1546 | ||
1527 | if (supply_rdev) | 1547 | if (rdev->supply) |
1528 | regulator_disable(get_device_regulator(rdev_get_dev(supply_rdev))); | 1548 | while (rdev->open_count--) |
1549 | regulator_disable(rdev->supply); | ||
1529 | 1550 | ||
1530 | return ret; | 1551 | return ret; |
1531 | } | 1552 | } |
@@ -2136,7 +2157,7 @@ int regulator_set_optimum_mode(struct regulator *regulator, int uA_load) | |||
2136 | /* get input voltage */ | 2157 | /* get input voltage */ |
2137 | input_uV = 0; | 2158 | input_uV = 0; |
2138 | if (rdev->supply) | 2159 | if (rdev->supply) |
2139 | input_uV = _regulator_get_voltage(rdev->supply); | 2160 | input_uV = regulator_get_voltage(rdev->supply); |
2140 | if (input_uV <= 0) | 2161 | if (input_uV <= 0) |
2141 | input_uV = rdev->constraints->input_uV; | 2162 | input_uV = rdev->constraints->input_uV; |
2142 | if (input_uV <= 0) { | 2163 | if (input_uV <= 0) { |
@@ -2206,17 +2227,8 @@ EXPORT_SYMBOL_GPL(regulator_unregister_notifier); | |||
2206 | static void _notifier_call_chain(struct regulator_dev *rdev, | 2227 | static void _notifier_call_chain(struct regulator_dev *rdev, |
2207 | unsigned long event, void *data) | 2228 | unsigned long event, void *data) |
2208 | { | 2229 | { |
2209 | struct regulator_dev *_rdev; | ||
2210 | |||
2211 | /* call rdev chain first */ | 2230 | /* call rdev chain first */ |
2212 | blocking_notifier_call_chain(&rdev->notifier, event, NULL); | 2231 | blocking_notifier_call_chain(&rdev->notifier, event, NULL); |
2213 | |||
2214 | /* now notify regulator we supply */ | ||
2215 | list_for_each_entry(_rdev, &rdev->supply_list, slist) { | ||
2216 | mutex_lock(&_rdev->mutex); | ||
2217 | _notifier_call_chain(_rdev, event, data); | ||
2218 | mutex_unlock(&_rdev->mutex); | ||
2219 | } | ||
2220 | } | 2232 | } |
2221 | 2233 | ||
2222 | /** | 2234 | /** |
@@ -2264,6 +2276,13 @@ err: | |||
2264 | } | 2276 | } |
2265 | EXPORT_SYMBOL_GPL(regulator_bulk_get); | 2277 | EXPORT_SYMBOL_GPL(regulator_bulk_get); |
2266 | 2278 | ||
2279 | static void regulator_bulk_enable_async(void *data, async_cookie_t cookie) | ||
2280 | { | ||
2281 | struct regulator_bulk_data *bulk = data; | ||
2282 | |||
2283 | bulk->ret = regulator_enable(bulk->consumer); | ||
2284 | } | ||
2285 | |||
2267 | /** | 2286 | /** |
2268 | * regulator_bulk_enable - enable multiple regulator consumers | 2287 | * regulator_bulk_enable - enable multiple regulator consumers |
2269 | * | 2288 | * |
@@ -2279,21 +2298,33 @@ EXPORT_SYMBOL_GPL(regulator_bulk_get); | |||
2279 | int regulator_bulk_enable(int num_consumers, | 2298 | int regulator_bulk_enable(int num_consumers, |
2280 | struct regulator_bulk_data *consumers) | 2299 | struct regulator_bulk_data *consumers) |
2281 | { | 2300 | { |
2301 | LIST_HEAD(async_domain); | ||
2282 | int i; | 2302 | int i; |
2283 | int ret; | 2303 | int ret = 0; |
2304 | |||
2305 | for (i = 0; i < num_consumers; i++) | ||
2306 | async_schedule_domain(regulator_bulk_enable_async, | ||
2307 | &consumers[i], &async_domain); | ||
2308 | |||
2309 | async_synchronize_full_domain(&async_domain); | ||
2284 | 2310 | ||
2311 | /* If any consumer failed we need to unwind any that succeeded */ | ||
2285 | for (i = 0; i < num_consumers; i++) { | 2312 | for (i = 0; i < num_consumers; i++) { |
2286 | ret = regulator_enable(consumers[i].consumer); | 2313 | if (consumers[i].ret != 0) { |
2287 | if (ret != 0) | 2314 | ret = consumers[i].ret; |
2288 | goto err; | 2315 | goto err; |
2316 | } | ||
2289 | } | 2317 | } |
2290 | 2318 | ||
2291 | return 0; | 2319 | return 0; |
2292 | 2320 | ||
2293 | err: | 2321 | err: |
2294 | pr_err("Failed to enable %s: %d\n", consumers[i].supply, ret); | 2322 | for (i = 0; i < num_consumers; i++) |
2295 | for (--i; i >= 0; --i) | 2323 | if (consumers[i].ret == 0) |
2296 | regulator_disable(consumers[i].consumer); | 2324 | regulator_disable(consumers[i].consumer); |
2325 | else | ||
2326 | pr_err("Failed to enable %s: %d\n", | ||
2327 | consumers[i].supply, consumers[i].ret); | ||
2297 | 2328 | ||
2298 | return ret; | 2329 | return ret; |
2299 | } | 2330 | } |
@@ -2589,9 +2620,7 @@ struct regulator_dev *regulator_register(struct regulator_desc *regulator_desc, | |||
2589 | rdev->owner = regulator_desc->owner; | 2620 | rdev->owner = regulator_desc->owner; |
2590 | rdev->desc = regulator_desc; | 2621 | rdev->desc = regulator_desc; |
2591 | INIT_LIST_HEAD(&rdev->consumer_list); | 2622 | INIT_LIST_HEAD(&rdev->consumer_list); |
2592 | INIT_LIST_HEAD(&rdev->supply_list); | ||
2593 | INIT_LIST_HEAD(&rdev->list); | 2623 | INIT_LIST_HEAD(&rdev->list); |
2594 | INIT_LIST_HEAD(&rdev->slist); | ||
2595 | BLOCKING_INIT_NOTIFIER_HEAD(&rdev->notifier); | 2624 | BLOCKING_INIT_NOTIFIER_HEAD(&rdev->notifier); |
2596 | 2625 | ||
2597 | /* preform any regulator specific init */ | 2626 | /* preform any regulator specific init */ |
@@ -2672,6 +2701,7 @@ unset_supplies: | |||
2672 | unset_regulator_supplies(rdev); | 2701 | unset_regulator_supplies(rdev); |
2673 | 2702 | ||
2674 | scrub: | 2703 | scrub: |
2704 | kfree(rdev->constraints); | ||
2675 | device_unregister(&rdev->dev); | 2705 | device_unregister(&rdev->dev); |
2676 | /* device core frees rdev */ | 2706 | /* device core frees rdev */ |
2677 | rdev = ERR_PTR(ret); | 2707 | rdev = ERR_PTR(ret); |
@@ -2703,7 +2733,7 @@ void regulator_unregister(struct regulator_dev *rdev) | |||
2703 | unset_regulator_supplies(rdev); | 2733 | unset_regulator_supplies(rdev); |
2704 | list_del(&rdev->list); | 2734 | list_del(&rdev->list); |
2705 | if (rdev->supply) | 2735 | if (rdev->supply) |
2706 | sysfs_remove_link(&rdev->dev.kobj, "supply"); | 2736 | regulator_put(rdev->supply); |
2707 | device_unregister(&rdev->dev); | 2737 | device_unregister(&rdev->dev); |
2708 | kfree(rdev->constraints); | 2738 | kfree(rdev->constraints); |
2709 | mutex_unlock(®ulator_list_mutex); | 2739 | mutex_unlock(®ulator_list_mutex); |
diff --git a/drivers/regulator/dummy.c b/drivers/regulator/dummy.c index c7410bde7b5d..f6ef6694ab98 100644 --- a/drivers/regulator/dummy.c +++ b/drivers/regulator/dummy.c | |||
@@ -36,6 +36,29 @@ static struct regulator_desc dummy_desc = { | |||
36 | .ops = &dummy_ops, | 36 | .ops = &dummy_ops, |
37 | }; | 37 | }; |
38 | 38 | ||
39 | static int __devinit dummy_regulator_probe(struct platform_device *pdev) | ||
40 | { | ||
41 | int ret; | ||
42 | |||
43 | dummy_regulator_rdev = regulator_register(&dummy_desc, NULL, | ||
44 | &dummy_initdata, NULL); | ||
45 | if (IS_ERR(dummy_regulator_rdev)) { | ||
46 | ret = PTR_ERR(dummy_regulator_rdev); | ||
47 | pr_err("Failed to register regulator: %d\n", ret); | ||
48 | return ret; | ||
49 | } | ||
50 | |||
51 | return 0; | ||
52 | } | ||
53 | |||
54 | static struct platform_driver dummy_regulator_driver = { | ||
55 | .probe = dummy_regulator_probe, | ||
56 | .driver = { | ||
57 | .name = "reg-dummy", | ||
58 | .owner = THIS_MODULE, | ||
59 | }, | ||
60 | }; | ||
61 | |||
39 | static struct platform_device *dummy_pdev; | 62 | static struct platform_device *dummy_pdev; |
40 | 63 | ||
41 | void __init regulator_dummy_init(void) | 64 | void __init regulator_dummy_init(void) |
@@ -55,12 +78,9 @@ void __init regulator_dummy_init(void) | |||
55 | return; | 78 | return; |
56 | } | 79 | } |
57 | 80 | ||
58 | dummy_regulator_rdev = regulator_register(&dummy_desc, NULL, | 81 | ret = platform_driver_register(&dummy_regulator_driver); |
59 | &dummy_initdata, NULL); | 82 | if (ret != 0) { |
60 | if (IS_ERR(dummy_regulator_rdev)) { | 83 | pr_err("Failed to register dummy regulator driver: %d\n", ret); |
61 | ret = PTR_ERR(dummy_regulator_rdev); | ||
62 | pr_err("Failed to register regulator: %d\n", ret); | ||
63 | platform_device_unregister(dummy_pdev); | 84 | platform_device_unregister(dummy_pdev); |
64 | return; | ||
65 | } | 85 | } |
66 | } | 86 | } |
diff --git a/drivers/regulator/tps65910-regulator.c b/drivers/regulator/tps65910-regulator.c index 55dd4e6650db..66d2d60b436a 100644 --- a/drivers/regulator/tps65910-regulator.c +++ b/drivers/regulator/tps65910-regulator.c | |||
@@ -49,7 +49,6 @@ | |||
49 | #define TPS65911_REG_LDO7 11 | 49 | #define TPS65911_REG_LDO7 11 |
50 | #define TPS65911_REG_LDO8 12 | 50 | #define TPS65911_REG_LDO8 12 |
51 | 51 | ||
52 | #define TPS65910_NUM_REGULATOR 13 | ||
53 | #define TPS65910_SUPPLY_STATE_ENABLED 0x1 | 52 | #define TPS65910_SUPPLY_STATE_ENABLED 0x1 |
54 | 53 | ||
55 | /* supported VIO voltages in milivolts */ | 54 | /* supported VIO voltages in milivolts */ |
@@ -264,11 +263,12 @@ static struct tps_info tps65911_regs[] = { | |||
264 | }; | 263 | }; |
265 | 264 | ||
266 | struct tps65910_reg { | 265 | struct tps65910_reg { |
267 | struct regulator_desc desc[TPS65910_NUM_REGULATOR]; | 266 | struct regulator_desc *desc; |
268 | struct tps65910 *mfd; | 267 | struct tps65910 *mfd; |
269 | struct regulator_dev *rdev[TPS65910_NUM_REGULATOR]; | 268 | struct regulator_dev **rdev; |
270 | struct tps_info *info[TPS65910_NUM_REGULATOR]; | 269 | struct tps_info **info; |
271 | struct mutex mutex; | 270 | struct mutex mutex; |
271 | int num_regulators; | ||
272 | int mode; | 272 | int mode; |
273 | int (*get_ctrl_reg)(int); | 273 | int (*get_ctrl_reg)(int); |
274 | }; | 274 | }; |
@@ -759,8 +759,13 @@ static int tps65910_list_voltage_dcdc(struct regulator_dev *dev, | |||
759 | mult = (selector / VDD1_2_NUM_VOLTS) + 1; | 759 | mult = (selector / VDD1_2_NUM_VOLTS) + 1; |
760 | volt = VDD1_2_MIN_VOLT + | 760 | volt = VDD1_2_MIN_VOLT + |
761 | (selector % VDD1_2_NUM_VOLTS) * VDD1_2_OFFSET; | 761 | (selector % VDD1_2_NUM_VOLTS) * VDD1_2_OFFSET; |
762 | break; | ||
762 | case TPS65911_REG_VDDCTRL: | 763 | case TPS65911_REG_VDDCTRL: |
763 | volt = VDDCTRL_MIN_VOLT + (selector * VDDCTRL_OFFSET); | 764 | volt = VDDCTRL_MIN_VOLT + (selector * VDDCTRL_OFFSET); |
765 | break; | ||
766 | default: | ||
767 | BUG(); | ||
768 | return -EINVAL; | ||
764 | } | 769 | } |
765 | 770 | ||
766 | return volt * 100 * mult; | 771 | return volt * 100 * mult; |
@@ -897,16 +902,42 @@ static __devinit int tps65910_probe(struct platform_device *pdev) | |||
897 | switch(tps65910_chip_id(tps65910)) { | 902 | switch(tps65910_chip_id(tps65910)) { |
898 | case TPS65910: | 903 | case TPS65910: |
899 | pmic->get_ctrl_reg = &tps65910_get_ctrl_register; | 904 | pmic->get_ctrl_reg = &tps65910_get_ctrl_register; |
905 | pmic->num_regulators = ARRAY_SIZE(tps65910_regs); | ||
900 | info = tps65910_regs; | 906 | info = tps65910_regs; |
907 | break; | ||
901 | case TPS65911: | 908 | case TPS65911: |
902 | pmic->get_ctrl_reg = &tps65911_get_ctrl_register; | 909 | pmic->get_ctrl_reg = &tps65911_get_ctrl_register; |
910 | pmic->num_regulators = ARRAY_SIZE(tps65911_regs); | ||
903 | info = tps65911_regs; | 911 | info = tps65911_regs; |
912 | break; | ||
904 | default: | 913 | default: |
905 | pr_err("Invalid tps chip version\n"); | 914 | pr_err("Invalid tps chip version\n"); |
915 | kfree(pmic); | ||
906 | return -ENODEV; | 916 | return -ENODEV; |
907 | } | 917 | } |
908 | 918 | ||
909 | for (i = 0; i < TPS65910_NUM_REGULATOR; i++, info++, reg_data++) { | 919 | pmic->desc = kcalloc(pmic->num_regulators, |
920 | sizeof(struct regulator_desc), GFP_KERNEL); | ||
921 | if (!pmic->desc) { | ||
922 | err = -ENOMEM; | ||
923 | goto err_free_pmic; | ||
924 | } | ||
925 | |||
926 | pmic->info = kcalloc(pmic->num_regulators, | ||
927 | sizeof(struct tps_info *), GFP_KERNEL); | ||
928 | if (!pmic->info) { | ||
929 | err = -ENOMEM; | ||
930 | goto err_free_desc; | ||
931 | } | ||
932 | |||
933 | pmic->rdev = kcalloc(pmic->num_regulators, | ||
934 | sizeof(struct regulator_dev *), GFP_KERNEL); | ||
935 | if (!pmic->rdev) { | ||
936 | err = -ENOMEM; | ||
937 | goto err_free_info; | ||
938 | } | ||
939 | |||
940 | for (i = 0; i < pmic->num_regulators; i++, info++, reg_data++) { | ||
910 | /* Register the regulators */ | 941 | /* Register the regulators */ |
911 | pmic->info[i] = info; | 942 | pmic->info[i] = info; |
912 | 943 | ||
@@ -938,7 +969,7 @@ static __devinit int tps65910_probe(struct platform_device *pdev) | |||
938 | "failed to register %s regulator\n", | 969 | "failed to register %s regulator\n", |
939 | pdev->name); | 970 | pdev->name); |
940 | err = PTR_ERR(rdev); | 971 | err = PTR_ERR(rdev); |
941 | goto err; | 972 | goto err_unregister_regulator; |
942 | } | 973 | } |
943 | 974 | ||
944 | /* Save regulator for cleanup */ | 975 | /* Save regulator for cleanup */ |
@@ -946,23 +977,31 @@ static __devinit int tps65910_probe(struct platform_device *pdev) | |||
946 | } | 977 | } |
947 | return 0; | 978 | return 0; |
948 | 979 | ||
949 | err: | 980 | err_unregister_regulator: |
950 | while (--i >= 0) | 981 | while (--i >= 0) |
951 | regulator_unregister(pmic->rdev[i]); | 982 | regulator_unregister(pmic->rdev[i]); |
952 | 983 | kfree(pmic->rdev); | |
984 | err_free_info: | ||
985 | kfree(pmic->info); | ||
986 | err_free_desc: | ||
987 | kfree(pmic->desc); | ||
988 | err_free_pmic: | ||
953 | kfree(pmic); | 989 | kfree(pmic); |
954 | return err; | 990 | return err; |
955 | } | 991 | } |
956 | 992 | ||
957 | static int __devexit tps65910_remove(struct platform_device *pdev) | 993 | static int __devexit tps65910_remove(struct platform_device *pdev) |
958 | { | 994 | { |
959 | struct tps65910_reg *tps65910_reg = platform_get_drvdata(pdev); | 995 | struct tps65910_reg *pmic = platform_get_drvdata(pdev); |
960 | int i; | 996 | int i; |
961 | 997 | ||
962 | for (i = 0; i < TPS65910_NUM_REGULATOR; i++) | 998 | for (i = 0; i < pmic->num_regulators; i++) |
963 | regulator_unregister(tps65910_reg->rdev[i]); | 999 | regulator_unregister(pmic->rdev[i]); |
964 | 1000 | ||
965 | kfree(tps65910_reg); | 1001 | kfree(pmic->rdev); |
1002 | kfree(pmic->info); | ||
1003 | kfree(pmic->desc); | ||
1004 | kfree(pmic); | ||
966 | return 0; | 1005 | return 0; |
967 | } | 1006 | } |
968 | 1007 | ||
diff --git a/drivers/regulator/twl-regulator.c b/drivers/regulator/twl-regulator.c index 87fe0f75a56e..ee8747f4fa08 100644 --- a/drivers/regulator/twl-regulator.c +++ b/drivers/regulator/twl-regulator.c | |||
@@ -835,8 +835,8 @@ static struct regulator_ops twlsmps_ops = { | |||
835 | remap_conf) \ | 835 | remap_conf) \ |
836 | TWL_FIXED_LDO(label, offset, mVolts, num, turnon_delay, \ | 836 | TWL_FIXED_LDO(label, offset, mVolts, num, turnon_delay, \ |
837 | remap_conf, TWL4030, twl4030fixed_ops) | 837 | remap_conf, TWL4030, twl4030fixed_ops) |
838 | #define TWL6030_FIXED_LDO(label, offset, mVolts, num, turnon_delay) \ | 838 | #define TWL6030_FIXED_LDO(label, offset, mVolts, turnon_delay) \ |
839 | TWL_FIXED_LDO(label, offset, mVolts, num, turnon_delay, \ | 839 | TWL_FIXED_LDO(label, offset, mVolts, 0x0, turnon_delay, \ |
840 | 0x0, TWL6030, twl6030fixed_ops) | 840 | 0x0, TWL6030, twl6030fixed_ops) |
841 | 841 | ||
842 | #define TWL4030_ADJUSTABLE_LDO(label, offset, num, turnon_delay, remap_conf) { \ | 842 | #define TWL4030_ADJUSTABLE_LDO(label, offset, num, turnon_delay, remap_conf) { \ |
@@ -856,24 +856,22 @@ static struct regulator_ops twlsmps_ops = { | |||
856 | }, \ | 856 | }, \ |
857 | } | 857 | } |
858 | 858 | ||
859 | #define TWL6030_ADJUSTABLE_LDO(label, offset, min_mVolts, max_mVolts, num) { \ | 859 | #define TWL6030_ADJUSTABLE_LDO(label, offset, min_mVolts, max_mVolts) { \ |
860 | .base = offset, \ | 860 | .base = offset, \ |
861 | .id = num, \ | ||
862 | .min_mV = min_mVolts, \ | 861 | .min_mV = min_mVolts, \ |
863 | .max_mV = max_mVolts, \ | 862 | .max_mV = max_mVolts, \ |
864 | .desc = { \ | 863 | .desc = { \ |
865 | .name = #label, \ | 864 | .name = #label, \ |
866 | .id = TWL6030_REG_##label, \ | 865 | .id = TWL6030_REG_##label, \ |
867 | .n_voltages = (max_mVolts - min_mVolts)/100, \ | 866 | .n_voltages = (max_mVolts - min_mVolts)/100 + 1, \ |
868 | .ops = &twl6030ldo_ops, \ | 867 | .ops = &twl6030ldo_ops, \ |
869 | .type = REGULATOR_VOLTAGE, \ | 868 | .type = REGULATOR_VOLTAGE, \ |
870 | .owner = THIS_MODULE, \ | 869 | .owner = THIS_MODULE, \ |
871 | }, \ | 870 | }, \ |
872 | } | 871 | } |
873 | 872 | ||
874 | #define TWL6025_ADJUSTABLE_LDO(label, offset, min_mVolts, max_mVolts, num) { \ | 873 | #define TWL6025_ADJUSTABLE_LDO(label, offset, min_mVolts, max_mVolts) { \ |
875 | .base = offset, \ | 874 | .base = offset, \ |
876 | .id = num, \ | ||
877 | .min_mV = min_mVolts, \ | 875 | .min_mV = min_mVolts, \ |
878 | .max_mV = max_mVolts, \ | 876 | .max_mV = max_mVolts, \ |
879 | .desc = { \ | 877 | .desc = { \ |
@@ -903,9 +901,8 @@ static struct regulator_ops twlsmps_ops = { | |||
903 | }, \ | 901 | }, \ |
904 | } | 902 | } |
905 | 903 | ||
906 | #define TWL6030_FIXED_RESOURCE(label, offset, num, turnon_delay) { \ | 904 | #define TWL6030_FIXED_RESOURCE(label, offset, turnon_delay) { \ |
907 | .base = offset, \ | 905 | .base = offset, \ |
908 | .id = num, \ | ||
909 | .delay = turnon_delay, \ | 906 | .delay = turnon_delay, \ |
910 | .desc = { \ | 907 | .desc = { \ |
911 | .name = #label, \ | 908 | .name = #label, \ |
@@ -916,9 +913,8 @@ static struct regulator_ops twlsmps_ops = { | |||
916 | }, \ | 913 | }, \ |
917 | } | 914 | } |
918 | 915 | ||
919 | #define TWL6025_ADJUSTABLE_SMPS(label, offset, num) { \ | 916 | #define TWL6025_ADJUSTABLE_SMPS(label, offset) { \ |
920 | .base = offset, \ | 917 | .base = offset, \ |
921 | .id = num, \ | ||
922 | .min_mV = 600, \ | 918 | .min_mV = 600, \ |
923 | .max_mV = 2100, \ | 919 | .max_mV = 2100, \ |
924 | .desc = { \ | 920 | .desc = { \ |
@@ -961,32 +957,32 @@ static struct twlreg_info twl_regs[] = { | |||
961 | /* 6030 REG with base as PMC Slave Misc : 0x0030 */ | 957 | /* 6030 REG with base as PMC Slave Misc : 0x0030 */ |
962 | /* Turnon-delay and remap configuration values for 6030 are not | 958 | /* Turnon-delay and remap configuration values for 6030 are not |
963 | verified since the specification is not public */ | 959 | verified since the specification is not public */ |
964 | TWL6030_ADJUSTABLE_LDO(VAUX1_6030, 0x54, 1000, 3300, 1), | 960 | TWL6030_ADJUSTABLE_LDO(VAUX1_6030, 0x54, 1000, 3300), |
965 | TWL6030_ADJUSTABLE_LDO(VAUX2_6030, 0x58, 1000, 3300, 2), | 961 | TWL6030_ADJUSTABLE_LDO(VAUX2_6030, 0x58, 1000, 3300), |
966 | TWL6030_ADJUSTABLE_LDO(VAUX3_6030, 0x5c, 1000, 3300, 3), | 962 | TWL6030_ADJUSTABLE_LDO(VAUX3_6030, 0x5c, 1000, 3300), |
967 | TWL6030_ADJUSTABLE_LDO(VMMC, 0x68, 1000, 3300, 4), | 963 | TWL6030_ADJUSTABLE_LDO(VMMC, 0x68, 1000, 3300), |
968 | TWL6030_ADJUSTABLE_LDO(VPP, 0x6c, 1000, 3300, 5), | 964 | TWL6030_ADJUSTABLE_LDO(VPP, 0x6c, 1000, 3300), |
969 | TWL6030_ADJUSTABLE_LDO(VUSIM, 0x74, 1000, 3300, 7), | 965 | TWL6030_ADJUSTABLE_LDO(VUSIM, 0x74, 1000, 3300), |
970 | TWL6030_FIXED_LDO(VANA, 0x50, 2100, 15, 0), | 966 | TWL6030_FIXED_LDO(VANA, 0x50, 2100, 0), |
971 | TWL6030_FIXED_LDO(VCXIO, 0x60, 1800, 16, 0), | 967 | TWL6030_FIXED_LDO(VCXIO, 0x60, 1800, 0), |
972 | TWL6030_FIXED_LDO(VDAC, 0x64, 1800, 17, 0), | 968 | TWL6030_FIXED_LDO(VDAC, 0x64, 1800, 0), |
973 | TWL6030_FIXED_LDO(VUSB, 0x70, 3300, 18, 0), | 969 | TWL6030_FIXED_LDO(VUSB, 0x70, 3300, 0), |
974 | TWL6030_FIXED_RESOURCE(CLK32KG, 0x8C, 48, 0), | 970 | TWL6030_FIXED_RESOURCE(CLK32KG, 0x8C, 0), |
975 | 971 | ||
976 | /* 6025 are renamed compared to 6030 versions */ | 972 | /* 6025 are renamed compared to 6030 versions */ |
977 | TWL6025_ADJUSTABLE_LDO(LDO2, 0x54, 1000, 3300, 1), | 973 | TWL6025_ADJUSTABLE_LDO(LDO2, 0x54, 1000, 3300), |
978 | TWL6025_ADJUSTABLE_LDO(LDO4, 0x58, 1000, 3300, 2), | 974 | TWL6025_ADJUSTABLE_LDO(LDO4, 0x58, 1000, 3300), |
979 | TWL6025_ADJUSTABLE_LDO(LDO3, 0x5c, 1000, 3300, 3), | 975 | TWL6025_ADJUSTABLE_LDO(LDO3, 0x5c, 1000, 3300), |
980 | TWL6025_ADJUSTABLE_LDO(LDO5, 0x68, 1000, 3300, 4), | 976 | TWL6025_ADJUSTABLE_LDO(LDO5, 0x68, 1000, 3300), |
981 | TWL6025_ADJUSTABLE_LDO(LDO1, 0x6c, 1000, 3300, 5), | 977 | TWL6025_ADJUSTABLE_LDO(LDO1, 0x6c, 1000, 3300), |
982 | TWL6025_ADJUSTABLE_LDO(LDO7, 0x74, 1000, 3300, 7), | 978 | TWL6025_ADJUSTABLE_LDO(LDO7, 0x74, 1000, 3300), |
983 | TWL6025_ADJUSTABLE_LDO(LDO6, 0x60, 1000, 3300, 16), | 979 | TWL6025_ADJUSTABLE_LDO(LDO6, 0x60, 1000, 3300), |
984 | TWL6025_ADJUSTABLE_LDO(LDOLN, 0x64, 1000, 3300, 17), | 980 | TWL6025_ADJUSTABLE_LDO(LDOLN, 0x64, 1000, 3300), |
985 | TWL6025_ADJUSTABLE_LDO(LDOUSB, 0x70, 1000, 3300, 18), | 981 | TWL6025_ADJUSTABLE_LDO(LDOUSB, 0x70, 1000, 3300), |
986 | 982 | ||
987 | TWL6025_ADJUSTABLE_SMPS(SMPS3, 0x34, 1), | 983 | TWL6025_ADJUSTABLE_SMPS(SMPS3, 0x34), |
988 | TWL6025_ADJUSTABLE_SMPS(SMPS4, 0x10, 2), | 984 | TWL6025_ADJUSTABLE_SMPS(SMPS4, 0x10), |
989 | TWL6025_ADJUSTABLE_SMPS(VIO, 0x16, 3), | 985 | TWL6025_ADJUSTABLE_SMPS(VIO, 0x16), |
990 | }; | 986 | }; |
991 | 987 | ||
992 | static u8 twl_get_smps_offset(void) | 988 | static u8 twl_get_smps_offset(void) |
diff --git a/drivers/regulator/wm831x-dcdc.c b/drivers/regulator/wm831x-dcdc.c index a0982e809851..bd3531d8b2ac 100644 --- a/drivers/regulator/wm831x-dcdc.c +++ b/drivers/regulator/wm831x-dcdc.c | |||
@@ -267,23 +267,6 @@ static int wm831x_buckv_select_min_voltage(struct regulator_dev *rdev, | |||
267 | return vsel; | 267 | return vsel; |
268 | } | 268 | } |
269 | 269 | ||
270 | static int wm831x_buckv_select_max_voltage(struct regulator_dev *rdev, | ||
271 | int min_uV, int max_uV) | ||
272 | { | ||
273 | u16 vsel; | ||
274 | |||
275 | if (max_uV < 600000 || max_uV > 1800000) | ||
276 | return -EINVAL; | ||
277 | |||
278 | vsel = ((max_uV - 600000) / 12500) + 8; | ||
279 | |||
280 | if (wm831x_buckv_list_voltage(rdev, vsel) < min_uV || | ||
281 | wm831x_buckv_list_voltage(rdev, vsel) < max_uV) | ||
282 | return -EINVAL; | ||
283 | |||
284 | return vsel; | ||
285 | } | ||
286 | |||
287 | static int wm831x_buckv_set_dvs(struct regulator_dev *rdev, int state) | 270 | static int wm831x_buckv_set_dvs(struct regulator_dev *rdev, int state) |
288 | { | 271 | { |
289 | struct wm831x_dcdc *dcdc = rdev_get_drvdata(rdev); | 272 | struct wm831x_dcdc *dcdc = rdev_get_drvdata(rdev); |
@@ -338,28 +321,23 @@ static int wm831x_buckv_set_voltage(struct regulator_dev *rdev, | |||
338 | if (ret < 0) | 321 | if (ret < 0) |
339 | return ret; | 322 | return ret; |
340 | 323 | ||
341 | /* Set the high voltage as the DVS voltage. This is optimised | 324 | /* |
342 | * for CPUfreq usage, most processors will keep the maximum | 325 | * If this VSEL is higher than the last one we've seen then |
343 | * voltage constant and lower the minimum with the frequency. */ | 326 | * remember it as the DVS VSEL. This is optimised for CPUfreq |
344 | vsel = wm831x_buckv_select_max_voltage(rdev, min_uV, max_uV); | 327 | * usage where we want to get to the highest voltage very |
345 | if (vsel < 0) { | 328 | * quickly. |
346 | /* This should never happen - at worst the same vsel | 329 | */ |
347 | * should be chosen */ | 330 | if (vsel > dcdc->dvs_vsel) { |
348 | WARN_ON(vsel < 0); | 331 | ret = wm831x_set_bits(wm831x, dvs_reg, |
349 | return 0; | 332 | WM831X_DC1_DVS_VSEL_MASK, |
333 | dcdc->dvs_vsel); | ||
334 | if (ret == 0) | ||
335 | dcdc->dvs_vsel = vsel; | ||
336 | else | ||
337 | dev_warn(wm831x->dev, | ||
338 | "Failed to set DCDC DVS VSEL: %d\n", ret); | ||
350 | } | 339 | } |
351 | 340 | ||
352 | /* Don't bother if it's the same VSEL we're already using */ | ||
353 | if (vsel == dcdc->on_vsel) | ||
354 | return 0; | ||
355 | |||
356 | ret = wm831x_set_bits(wm831x, dvs_reg, WM831X_DC1_DVS_VSEL_MASK, vsel); | ||
357 | if (ret == 0) | ||
358 | dcdc->dvs_vsel = vsel; | ||
359 | else | ||
360 | dev_warn(wm831x->dev, "Failed to set DCDC DVS VSEL: %d\n", | ||
361 | ret); | ||
362 | |||
363 | return 0; | 341 | return 0; |
364 | } | 342 | } |
365 | 343 | ||
@@ -456,27 +434,6 @@ static __devinit void wm831x_buckv_dvs_init(struct wm831x_dcdc *dcdc, | |||
456 | if (!pdata || !pdata->dvs_gpio) | 434 | if (!pdata || !pdata->dvs_gpio) |
457 | return; | 435 | return; |
458 | 436 | ||
459 | switch (pdata->dvs_control_src) { | ||
460 | case 1: | ||
461 | ctrl = 2 << WM831X_DC1_DVS_SRC_SHIFT; | ||
462 | break; | ||
463 | case 2: | ||
464 | ctrl = 3 << WM831X_DC1_DVS_SRC_SHIFT; | ||
465 | break; | ||
466 | default: | ||
467 | dev_err(wm831x->dev, "Invalid DVS control source %d for %s\n", | ||
468 | pdata->dvs_control_src, dcdc->name); | ||
469 | return; | ||
470 | } | ||
471 | |||
472 | ret = wm831x_set_bits(wm831x, dcdc->base + WM831X_DCDC_DVS_CONTROL, | ||
473 | WM831X_DC1_DVS_SRC_MASK, ctrl); | ||
474 | if (ret < 0) { | ||
475 | dev_err(wm831x->dev, "Failed to set %s DVS source: %d\n", | ||
476 | dcdc->name, ret); | ||
477 | return; | ||
478 | } | ||
479 | |||
480 | ret = gpio_request(pdata->dvs_gpio, "DCDC DVS"); | 437 | ret = gpio_request(pdata->dvs_gpio, "DCDC DVS"); |
481 | if (ret < 0) { | 438 | if (ret < 0) { |
482 | dev_err(wm831x->dev, "Failed to get %s DVS GPIO: %d\n", | 439 | dev_err(wm831x->dev, "Failed to get %s DVS GPIO: %d\n", |
@@ -498,17 +455,57 @@ static __devinit void wm831x_buckv_dvs_init(struct wm831x_dcdc *dcdc, | |||
498 | } | 455 | } |
499 | 456 | ||
500 | dcdc->dvs_gpio = pdata->dvs_gpio; | 457 | dcdc->dvs_gpio = pdata->dvs_gpio; |
458 | |||
459 | switch (pdata->dvs_control_src) { | ||
460 | case 1: | ||
461 | ctrl = 2 << WM831X_DC1_DVS_SRC_SHIFT; | ||
462 | break; | ||
463 | case 2: | ||
464 | ctrl = 3 << WM831X_DC1_DVS_SRC_SHIFT; | ||
465 | break; | ||
466 | default: | ||
467 | dev_err(wm831x->dev, "Invalid DVS control source %d for %s\n", | ||
468 | pdata->dvs_control_src, dcdc->name); | ||
469 | return; | ||
470 | } | ||
471 | |||
472 | /* If DVS_VSEL is set to the minimum value then raise it to ON_VSEL | ||
473 | * to make bootstrapping a bit smoother. | ||
474 | */ | ||
475 | if (!dcdc->dvs_vsel) { | ||
476 | ret = wm831x_set_bits(wm831x, | ||
477 | dcdc->base + WM831X_DCDC_DVS_CONTROL, | ||
478 | WM831X_DC1_DVS_VSEL_MASK, dcdc->on_vsel); | ||
479 | if (ret == 0) | ||
480 | dcdc->dvs_vsel = dcdc->on_vsel; | ||
481 | else | ||
482 | dev_warn(wm831x->dev, "Failed to set DVS_VSEL: %d\n", | ||
483 | ret); | ||
484 | } | ||
485 | |||
486 | ret = wm831x_set_bits(wm831x, dcdc->base + WM831X_DCDC_DVS_CONTROL, | ||
487 | WM831X_DC1_DVS_SRC_MASK, ctrl); | ||
488 | if (ret < 0) { | ||
489 | dev_err(wm831x->dev, "Failed to set %s DVS source: %d\n", | ||
490 | dcdc->name, ret); | ||
491 | } | ||
501 | } | 492 | } |
502 | 493 | ||
503 | static __devinit int wm831x_buckv_probe(struct platform_device *pdev) | 494 | static __devinit int wm831x_buckv_probe(struct platform_device *pdev) |
504 | { | 495 | { |
505 | struct wm831x *wm831x = dev_get_drvdata(pdev->dev.parent); | 496 | struct wm831x *wm831x = dev_get_drvdata(pdev->dev.parent); |
506 | struct wm831x_pdata *pdata = wm831x->dev->platform_data; | 497 | struct wm831x_pdata *pdata = wm831x->dev->platform_data; |
507 | int id = pdev->id % ARRAY_SIZE(pdata->dcdc); | 498 | int id; |
508 | struct wm831x_dcdc *dcdc; | 499 | struct wm831x_dcdc *dcdc; |
509 | struct resource *res; | 500 | struct resource *res; |
510 | int ret, irq; | 501 | int ret, irq; |
511 | 502 | ||
503 | if (pdata && pdata->wm831x_num) | ||
504 | id = (pdata->wm831x_num * 10) + 1; | ||
505 | else | ||
506 | id = 0; | ||
507 | id = pdev->id - id; | ||
508 | |||
512 | dev_dbg(&pdev->dev, "Probing DCDC%d\n", id + 1); | 509 | dev_dbg(&pdev->dev, "Probing DCDC%d\n", id + 1); |
513 | 510 | ||
514 | if (pdata == NULL || pdata->dcdc[id] == NULL) | 511 | if (pdata == NULL || pdata->dcdc[id] == NULL) |
@@ -545,7 +542,7 @@ static __devinit int wm831x_buckv_probe(struct platform_device *pdev) | |||
545 | } | 542 | } |
546 | dcdc->on_vsel = ret & WM831X_DC1_ON_VSEL_MASK; | 543 | dcdc->on_vsel = ret & WM831X_DC1_ON_VSEL_MASK; |
547 | 544 | ||
548 | ret = wm831x_reg_read(wm831x, dcdc->base + WM831X_DCDC_ON_CONFIG); | 545 | ret = wm831x_reg_read(wm831x, dcdc->base + WM831X_DCDC_DVS_CONTROL); |
549 | if (ret < 0) { | 546 | if (ret < 0) { |
550 | dev_err(wm831x->dev, "Failed to read DVS VSEL: %d\n", ret); | 547 | dev_err(wm831x->dev, "Failed to read DVS VSEL: %d\n", ret); |
551 | goto err; | 548 | goto err; |
@@ -709,11 +706,17 @@ static __devinit int wm831x_buckp_probe(struct platform_device *pdev) | |||
709 | { | 706 | { |
710 | struct wm831x *wm831x = dev_get_drvdata(pdev->dev.parent); | 707 | struct wm831x *wm831x = dev_get_drvdata(pdev->dev.parent); |
711 | struct wm831x_pdata *pdata = wm831x->dev->platform_data; | 708 | struct wm831x_pdata *pdata = wm831x->dev->platform_data; |
712 | int id = pdev->id % ARRAY_SIZE(pdata->dcdc); | 709 | int id; |
713 | struct wm831x_dcdc *dcdc; | 710 | struct wm831x_dcdc *dcdc; |
714 | struct resource *res; | 711 | struct resource *res; |
715 | int ret, irq; | 712 | int ret, irq; |
716 | 713 | ||
714 | if (pdata && pdata->wm831x_num) | ||
715 | id = (pdata->wm831x_num * 10) + 1; | ||
716 | else | ||
717 | id = 0; | ||
718 | id = pdev->id - id; | ||
719 | |||
717 | dev_dbg(&pdev->dev, "Probing DCDC%d\n", id + 1); | 720 | dev_dbg(&pdev->dev, "Probing DCDC%d\n", id + 1); |
718 | 721 | ||
719 | if (pdata == NULL || pdata->dcdc[id] == NULL) | 722 | if (pdata == NULL || pdata->dcdc[id] == NULL) |
@@ -1046,3 +1049,4 @@ MODULE_DESCRIPTION("WM831x DC-DC convertor driver"); | |||
1046 | MODULE_LICENSE("GPL"); | 1049 | MODULE_LICENSE("GPL"); |
1047 | MODULE_ALIAS("platform:wm831x-buckv"); | 1050 | MODULE_ALIAS("platform:wm831x-buckv"); |
1048 | MODULE_ALIAS("platform:wm831x-buckp"); | 1051 | MODULE_ALIAS("platform:wm831x-buckp"); |
1052 | MODULE_ALIAS("platform:wm831x-epe"); | ||
diff --git a/drivers/regulator/wm831x-ldo.c b/drivers/regulator/wm831x-ldo.c index 2220cf8defb1..6709710a059e 100644 --- a/drivers/regulator/wm831x-ldo.c +++ b/drivers/regulator/wm831x-ldo.c | |||
@@ -310,11 +310,17 @@ static __devinit int wm831x_gp_ldo_probe(struct platform_device *pdev) | |||
310 | { | 310 | { |
311 | struct wm831x *wm831x = dev_get_drvdata(pdev->dev.parent); | 311 | struct wm831x *wm831x = dev_get_drvdata(pdev->dev.parent); |
312 | struct wm831x_pdata *pdata = wm831x->dev->platform_data; | 312 | struct wm831x_pdata *pdata = wm831x->dev->platform_data; |
313 | int id = pdev->id % ARRAY_SIZE(pdata->ldo); | 313 | int id; |
314 | struct wm831x_ldo *ldo; | 314 | struct wm831x_ldo *ldo; |
315 | struct resource *res; | 315 | struct resource *res; |
316 | int ret, irq; | 316 | int ret, irq; |
317 | 317 | ||
318 | if (pdata && pdata->wm831x_num) | ||
319 | id = (pdata->wm831x_num * 10) + 1; | ||
320 | else | ||
321 | id = 0; | ||
322 | id = pdev->id - id; | ||
323 | |||
318 | dev_dbg(&pdev->dev, "Probing LDO%d\n", id + 1); | 324 | dev_dbg(&pdev->dev, "Probing LDO%d\n", id + 1); |
319 | 325 | ||
320 | if (pdata == NULL || pdata->ldo[id] == NULL) | 326 | if (pdata == NULL || pdata->ldo[id] == NULL) |
@@ -574,11 +580,17 @@ static __devinit int wm831x_aldo_probe(struct platform_device *pdev) | |||
574 | { | 580 | { |
575 | struct wm831x *wm831x = dev_get_drvdata(pdev->dev.parent); | 581 | struct wm831x *wm831x = dev_get_drvdata(pdev->dev.parent); |
576 | struct wm831x_pdata *pdata = wm831x->dev->platform_data; | 582 | struct wm831x_pdata *pdata = wm831x->dev->platform_data; |
577 | int id = pdev->id % ARRAY_SIZE(pdata->ldo); | 583 | int id; |
578 | struct wm831x_ldo *ldo; | 584 | struct wm831x_ldo *ldo; |
579 | struct resource *res; | 585 | struct resource *res; |
580 | int ret, irq; | 586 | int ret, irq; |
581 | 587 | ||
588 | if (pdata && pdata->wm831x_num) | ||
589 | id = (pdata->wm831x_num * 10) + 1; | ||
590 | else | ||
591 | id = 0; | ||
592 | id = pdev->id - id; | ||
593 | |||
582 | dev_dbg(&pdev->dev, "Probing LDO%d\n", id + 1); | 594 | dev_dbg(&pdev->dev, "Probing LDO%d\n", id + 1); |
583 | 595 | ||
584 | if (pdata == NULL || pdata->ldo[id] == NULL) | 596 | if (pdata == NULL || pdata->ldo[id] == NULL) |
@@ -764,11 +776,18 @@ static __devinit int wm831x_alive_ldo_probe(struct platform_device *pdev) | |||
764 | { | 776 | { |
765 | struct wm831x *wm831x = dev_get_drvdata(pdev->dev.parent); | 777 | struct wm831x *wm831x = dev_get_drvdata(pdev->dev.parent); |
766 | struct wm831x_pdata *pdata = wm831x->dev->platform_data; | 778 | struct wm831x_pdata *pdata = wm831x->dev->platform_data; |
767 | int id = pdev->id % ARRAY_SIZE(pdata->ldo); | 779 | int id; |
768 | struct wm831x_ldo *ldo; | 780 | struct wm831x_ldo *ldo; |
769 | struct resource *res; | 781 | struct resource *res; |
770 | int ret; | 782 | int ret; |
771 | 783 | ||
784 | if (pdata && pdata->wm831x_num) | ||
785 | id = (pdata->wm831x_num * 10) + 1; | ||
786 | else | ||
787 | id = 0; | ||
788 | id = pdev->id - id; | ||
789 | |||
790 | |||
772 | dev_dbg(&pdev->dev, "Probing LDO%d\n", id + 1); | 791 | dev_dbg(&pdev->dev, "Probing LDO%d\n", id + 1); |
773 | 792 | ||
774 | if (pdata == NULL || pdata->ldo[id] == NULL) | 793 | if (pdata == NULL || pdata->ldo[id] == NULL) |
diff --git a/drivers/regulator/wm8994-regulator.c b/drivers/regulator/wm8994-regulator.c index 35b2958d5106..1a6a690f24db 100644 --- a/drivers/regulator/wm8994-regulator.c +++ b/drivers/regulator/wm8994-regulator.c | |||
@@ -43,7 +43,7 @@ static int wm8994_ldo_enable(struct regulator_dev *rdev) | |||
43 | if (!ldo->enable) | 43 | if (!ldo->enable) |
44 | return 0; | 44 | return 0; |
45 | 45 | ||
46 | gpio_set_value(ldo->enable, 1); | 46 | gpio_set_value_cansleep(ldo->enable, 1); |
47 | ldo->is_enabled = true; | 47 | ldo->is_enabled = true; |
48 | 48 | ||
49 | return 0; | 49 | return 0; |
@@ -57,7 +57,7 @@ static int wm8994_ldo_disable(struct regulator_dev *rdev) | |||
57 | if (!ldo->enable) | 57 | if (!ldo->enable) |
58 | return -EINVAL; | 58 | return -EINVAL; |
59 | 59 | ||
60 | gpio_set_value(ldo->enable, 0); | 60 | gpio_set_value_cansleep(ldo->enable, 0); |
61 | ldo->is_enabled = false; | 61 | ldo->is_enabled = false; |
62 | 62 | ||
63 | return 0; | 63 | return 0; |