diff options
-rw-r--r-- | drivers/regulator/core.c | 101 | ||||
-rw-r--r-- | include/linux/regulator/driver.h | 4 |
2 files changed, 37 insertions, 68 deletions
diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index e3b67ee48b23..f0cc3983ffee 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c | |||
@@ -82,8 +82,7 @@ struct regulator { | |||
82 | }; | 82 | }; |
83 | 83 | ||
84 | static int _regulator_is_enabled(struct regulator_dev *rdev); | 84 | static int _regulator_is_enabled(struct regulator_dev *rdev); |
85 | static int _regulator_disable(struct regulator_dev *rdev, | 85 | static int _regulator_disable(struct regulator_dev *rdev); |
86 | struct regulator_dev **supply_rdev_ptr); | ||
87 | static int _regulator_get_voltage(struct regulator_dev *rdev); | 86 | static int _regulator_get_voltage(struct regulator_dev *rdev); |
88 | static int _regulator_get_current_limit(struct regulator_dev *rdev); | 87 | static int _regulator_get_current_limit(struct regulator_dev *rdev); |
89 | static unsigned int _regulator_get_mode(struct regulator_dev *rdev); | 88 | static unsigned int _regulator_get_mode(struct regulator_dev *rdev); |
@@ -91,6 +90,9 @@ static void _notifier_call_chain(struct regulator_dev *rdev, | |||
91 | unsigned long event, void *data); | 90 | unsigned long event, void *data); |
92 | static int _regulator_do_set_voltage(struct regulator_dev *rdev, | 91 | static int _regulator_do_set_voltage(struct regulator_dev *rdev, |
93 | int min_uV, int max_uV); | 92 | int min_uV, int max_uV); |
93 | static struct regulator *create_regulator(struct regulator_dev *rdev, | ||
94 | struct device *dev, | ||
95 | const char *supply_name); | ||
94 | 96 | ||
95 | static const char *rdev_get_name(struct regulator_dev *rdev) | 97 | static const char *rdev_get_name(struct regulator_dev *rdev) |
96 | { | 98 | { |
@@ -930,21 +932,20 @@ out: | |||
930 | * core if it's child is enabled. | 932 | * core if it's child is enabled. |
931 | */ | 933 | */ |
932 | static int set_supply(struct regulator_dev *rdev, | 934 | static int set_supply(struct regulator_dev *rdev, |
933 | struct regulator_dev *supply_rdev) | 935 | struct regulator_dev *supply_rdev) |
934 | { | 936 | { |
935 | int err; | 937 | int err; |
936 | 938 | ||
937 | err = sysfs_create_link(&rdev->dev.kobj, &supply_rdev->dev.kobj, | 939 | rdev_info(rdev, "supplied by %s\n", rdev_get_name(supply_rdev)); |
938 | "supply"); | 940 | |
939 | if (err) { | 941 | rdev->supply = create_regulator(supply_rdev, &rdev->dev, "SUPPLY"); |
940 | rdev_err(rdev, "could not add device link %s err %d\n", | 942 | if (IS_ERR(rdev->supply)) { |
941 | supply_rdev->dev.kobj.name, err); | 943 | err = PTR_ERR(rdev->supply); |
942 | goto out; | 944 | rdev->supply = NULL; |
945 | return err; | ||
943 | } | 946 | } |
944 | rdev->supply = supply_rdev; | 947 | |
945 | list_add(&rdev->slist, &supply_rdev->supply_list); | 948 | return 0; |
946 | out: | ||
947 | return err; | ||
948 | } | 949 | } |
949 | 950 | ||
950 | /** | 951 | /** |
@@ -1303,19 +1304,6 @@ static int _regulator_enable(struct regulator_dev *rdev) | |||
1303 | { | 1304 | { |
1304 | int ret, delay; | 1305 | int ret, delay; |
1305 | 1306 | ||
1306 | if (rdev->use_count == 0) { | ||
1307 | /* do we need to enable the supply regulator first */ | ||
1308 | if (rdev->supply) { | ||
1309 | mutex_lock(&rdev->supply->mutex); | ||
1310 | ret = _regulator_enable(rdev->supply); | ||
1311 | mutex_unlock(&rdev->supply->mutex); | ||
1312 | if (ret < 0) { | ||
1313 | rdev_err(rdev, "failed to enable: %d\n", ret); | ||
1314 | return ret; | ||
1315 | } | ||
1316 | } | ||
1317 | } | ||
1318 | |||
1319 | /* check voltage and requested load before enabling */ | 1307 | /* check voltage and requested load before enabling */ |
1320 | if (rdev->constraints && | 1308 | if (rdev->constraints && |
1321 | (rdev->constraints->valid_ops_mask & REGULATOR_CHANGE_DRMS)) | 1309 | (rdev->constraints->valid_ops_mask & REGULATOR_CHANGE_DRMS)) |
@@ -1390,19 +1378,27 @@ int regulator_enable(struct regulator *regulator) | |||
1390 | struct regulator_dev *rdev = regulator->rdev; | 1378 | struct regulator_dev *rdev = regulator->rdev; |
1391 | int ret = 0; | 1379 | int ret = 0; |
1392 | 1380 | ||
1381 | if (rdev->supply) { | ||
1382 | ret = regulator_enable(rdev->supply); | ||
1383 | if (ret != 0) | ||
1384 | return ret; | ||
1385 | } | ||
1386 | |||
1393 | mutex_lock(&rdev->mutex); | 1387 | mutex_lock(&rdev->mutex); |
1394 | ret = _regulator_enable(rdev); | 1388 | ret = _regulator_enable(rdev); |
1395 | mutex_unlock(&rdev->mutex); | 1389 | mutex_unlock(&rdev->mutex); |
1390 | |||
1391 | if (ret != 0) | ||
1392 | regulator_disable(rdev->supply); | ||
1393 | |||
1396 | return ret; | 1394 | return ret; |
1397 | } | 1395 | } |
1398 | EXPORT_SYMBOL_GPL(regulator_enable); | 1396 | EXPORT_SYMBOL_GPL(regulator_enable); |
1399 | 1397 | ||
1400 | /* locks held by regulator_disable() */ | 1398 | /* locks held by regulator_disable() */ |
1401 | static int _regulator_disable(struct regulator_dev *rdev, | 1399 | static int _regulator_disable(struct regulator_dev *rdev) |
1402 | struct regulator_dev **supply_rdev_ptr) | ||
1403 | { | 1400 | { |
1404 | int ret = 0; | 1401 | int ret = 0; |
1405 | *supply_rdev_ptr = NULL; | ||
1406 | 1402 | ||
1407 | if (WARN(rdev->use_count <= 0, | 1403 | if (WARN(rdev->use_count <= 0, |
1408 | "unbalanced disables for %s\n", rdev_get_name(rdev))) | 1404 | "unbalanced disables for %s\n", rdev_get_name(rdev))) |
@@ -1429,9 +1425,6 @@ static int _regulator_disable(struct regulator_dev *rdev, | |||
1429 | NULL); | 1425 | NULL); |
1430 | } | 1426 | } |
1431 | 1427 | ||
1432 | /* decrease our supplies ref count and disable if required */ | ||
1433 | *supply_rdev_ptr = rdev->supply; | ||
1434 | |||
1435 | rdev->use_count = 0; | 1428 | rdev->use_count = 0; |
1436 | } else if (rdev->use_count > 1) { | 1429 | } else if (rdev->use_count > 1) { |
1437 | 1430 | ||
@@ -1442,6 +1435,7 @@ static int _regulator_disable(struct regulator_dev *rdev, | |||
1442 | 1435 | ||
1443 | rdev->use_count--; | 1436 | rdev->use_count--; |
1444 | } | 1437 | } |
1438 | |||
1445 | return ret; | 1439 | return ret; |
1446 | } | 1440 | } |
1447 | 1441 | ||
@@ -1460,29 +1454,21 @@ static int _regulator_disable(struct regulator_dev *rdev, | |||
1460 | int regulator_disable(struct regulator *regulator) | 1454 | int regulator_disable(struct regulator *regulator) |
1461 | { | 1455 | { |
1462 | struct regulator_dev *rdev = regulator->rdev; | 1456 | struct regulator_dev *rdev = regulator->rdev; |
1463 | struct regulator_dev *supply_rdev = NULL; | ||
1464 | int ret = 0; | 1457 | int ret = 0; |
1465 | 1458 | ||
1466 | mutex_lock(&rdev->mutex); | 1459 | mutex_lock(&rdev->mutex); |
1467 | ret = _regulator_disable(rdev, &supply_rdev); | 1460 | ret = _regulator_disable(rdev); |
1468 | mutex_unlock(&rdev->mutex); | 1461 | mutex_unlock(&rdev->mutex); |
1469 | 1462 | ||
1470 | /* decrease our supplies ref count and disable if required */ | 1463 | if (ret == 0 && rdev->supply) |
1471 | while (supply_rdev != NULL) { | 1464 | regulator_disable(rdev->supply); |
1472 | rdev = supply_rdev; | ||
1473 | |||
1474 | mutex_lock(&rdev->mutex); | ||
1475 | _regulator_disable(rdev, &supply_rdev); | ||
1476 | mutex_unlock(&rdev->mutex); | ||
1477 | } | ||
1478 | 1465 | ||
1479 | return ret; | 1466 | return ret; |
1480 | } | 1467 | } |
1481 | EXPORT_SYMBOL_GPL(regulator_disable); | 1468 | EXPORT_SYMBOL_GPL(regulator_disable); |
1482 | 1469 | ||
1483 | /* locks held by regulator_force_disable() */ | 1470 | /* locks held by regulator_force_disable() */ |
1484 | static int _regulator_force_disable(struct regulator_dev *rdev, | 1471 | static int _regulator_force_disable(struct regulator_dev *rdev) |
1485 | struct regulator_dev **supply_rdev_ptr) | ||
1486 | { | 1472 | { |
1487 | int ret = 0; | 1473 | int ret = 0; |
1488 | 1474 | ||
@@ -1499,10 +1485,6 @@ static int _regulator_force_disable(struct regulator_dev *rdev, | |||
1499 | REGULATOR_EVENT_DISABLE, NULL); | 1485 | REGULATOR_EVENT_DISABLE, NULL); |
1500 | } | 1486 | } |
1501 | 1487 | ||
1502 | /* decrease our supplies ref count and disable if required */ | ||
1503 | *supply_rdev_ptr = rdev->supply; | ||
1504 | |||
1505 | rdev->use_count = 0; | ||
1506 | return ret; | 1488 | return ret; |
1507 | } | 1489 | } |
1508 | 1490 | ||
@@ -1518,16 +1500,16 @@ static int _regulator_force_disable(struct regulator_dev *rdev, | |||
1518 | int regulator_force_disable(struct regulator *regulator) | 1500 | int regulator_force_disable(struct regulator *regulator) |
1519 | { | 1501 | { |
1520 | struct regulator_dev *rdev = regulator->rdev; | 1502 | struct regulator_dev *rdev = regulator->rdev; |
1521 | struct regulator_dev *supply_rdev = NULL; | ||
1522 | int ret; | 1503 | int ret; |
1523 | 1504 | ||
1524 | mutex_lock(&rdev->mutex); | 1505 | mutex_lock(&rdev->mutex); |
1525 | regulator->uA_load = 0; | 1506 | regulator->uA_load = 0; |
1526 | ret = _regulator_force_disable(rdev, &supply_rdev); | 1507 | ret = _regulator_force_disable(regulator->rdev); |
1527 | mutex_unlock(&rdev->mutex); | 1508 | mutex_unlock(&rdev->mutex); |
1528 | 1509 | ||
1529 | if (supply_rdev) | 1510 | if (rdev->supply) |
1530 | regulator_disable(get_device_regulator(rdev_get_dev(supply_rdev))); | 1511 | while (rdev->open_count--) |
1512 | regulator_disable(rdev->supply); | ||
1531 | 1513 | ||
1532 | return ret; | 1514 | return ret; |
1533 | } | 1515 | } |
@@ -2138,7 +2120,7 @@ int regulator_set_optimum_mode(struct regulator *regulator, int uA_load) | |||
2138 | /* get input voltage */ | 2120 | /* get input voltage */ |
2139 | input_uV = 0; | 2121 | input_uV = 0; |
2140 | if (rdev->supply) | 2122 | if (rdev->supply) |
2141 | input_uV = _regulator_get_voltage(rdev->supply); | 2123 | input_uV = regulator_get_voltage(rdev->supply); |
2142 | if (input_uV <= 0) | 2124 | if (input_uV <= 0) |
2143 | input_uV = rdev->constraints->input_uV; | 2125 | input_uV = rdev->constraints->input_uV; |
2144 | if (input_uV <= 0) { | 2126 | if (input_uV <= 0) { |
@@ -2208,17 +2190,8 @@ EXPORT_SYMBOL_GPL(regulator_unregister_notifier); | |||
2208 | static void _notifier_call_chain(struct regulator_dev *rdev, | 2190 | static void _notifier_call_chain(struct regulator_dev *rdev, |
2209 | unsigned long event, void *data) | 2191 | unsigned long event, void *data) |
2210 | { | 2192 | { |
2211 | struct regulator_dev *_rdev; | ||
2212 | |||
2213 | /* call rdev chain first */ | 2193 | /* call rdev chain first */ |
2214 | blocking_notifier_call_chain(&rdev->notifier, event, NULL); | 2194 | blocking_notifier_call_chain(&rdev->notifier, event, NULL); |
2215 | |||
2216 | /* now notify regulator we supply */ | ||
2217 | list_for_each_entry(_rdev, &rdev->supply_list, slist) { | ||
2218 | mutex_lock(&_rdev->mutex); | ||
2219 | _notifier_call_chain(_rdev, event, data); | ||
2220 | mutex_unlock(&_rdev->mutex); | ||
2221 | } | ||
2222 | } | 2195 | } |
2223 | 2196 | ||
2224 | /** | 2197 | /** |
@@ -2610,9 +2583,7 @@ struct regulator_dev *regulator_register(struct regulator_desc *regulator_desc, | |||
2610 | rdev->owner = regulator_desc->owner; | 2583 | rdev->owner = regulator_desc->owner; |
2611 | rdev->desc = regulator_desc; | 2584 | rdev->desc = regulator_desc; |
2612 | INIT_LIST_HEAD(&rdev->consumer_list); | 2585 | INIT_LIST_HEAD(&rdev->consumer_list); |
2613 | INIT_LIST_HEAD(&rdev->supply_list); | ||
2614 | INIT_LIST_HEAD(&rdev->list); | 2586 | INIT_LIST_HEAD(&rdev->list); |
2615 | INIT_LIST_HEAD(&rdev->slist); | ||
2616 | BLOCKING_INIT_NOTIFIER_HEAD(&rdev->notifier); | 2587 | BLOCKING_INIT_NOTIFIER_HEAD(&rdev->notifier); |
2617 | 2588 | ||
2618 | /* preform any regulator specific init */ | 2589 | /* preform any regulator specific init */ |
@@ -2724,7 +2695,7 @@ void regulator_unregister(struct regulator_dev *rdev) | |||
2724 | unset_regulator_supplies(rdev); | 2695 | unset_regulator_supplies(rdev); |
2725 | list_del(&rdev->list); | 2696 | list_del(&rdev->list); |
2726 | if (rdev->supply) | 2697 | if (rdev->supply) |
2727 | sysfs_remove_link(&rdev->dev.kobj, "supply"); | 2698 | regulator_put(rdev->supply); |
2728 | device_unregister(&rdev->dev); | 2699 | device_unregister(&rdev->dev); |
2729 | kfree(rdev->constraints); | 2700 | kfree(rdev->constraints); |
2730 | mutex_unlock(®ulator_list_mutex); | 2701 | mutex_unlock(®ulator_list_mutex); |
diff --git a/include/linux/regulator/driver.h b/include/linux/regulator/driver.h index 6c433b89c80d..1a80bc77517d 100644 --- a/include/linux/regulator/driver.h +++ b/include/linux/regulator/driver.h | |||
@@ -188,18 +188,16 @@ struct regulator_dev { | |||
188 | 188 | ||
189 | /* lists we belong to */ | 189 | /* lists we belong to */ |
190 | struct list_head list; /* list of all regulators */ | 190 | struct list_head list; /* list of all regulators */ |
191 | struct list_head slist; /* list of supplied regulators */ | ||
192 | 191 | ||
193 | /* lists we own */ | 192 | /* lists we own */ |
194 | struct list_head consumer_list; /* consumers we supply */ | 193 | struct list_head consumer_list; /* consumers we supply */ |
195 | struct list_head supply_list; /* regulators we supply */ | ||
196 | 194 | ||
197 | struct blocking_notifier_head notifier; | 195 | struct blocking_notifier_head notifier; |
198 | struct mutex mutex; /* consumer lock */ | 196 | struct mutex mutex; /* consumer lock */ |
199 | struct module *owner; | 197 | struct module *owner; |
200 | struct device dev; | 198 | struct device dev; |
201 | struct regulation_constraints *constraints; | 199 | struct regulation_constraints *constraints; |
202 | struct regulator_dev *supply; /* for tree */ | 200 | struct regulator *supply; /* for tree */ |
203 | 201 | ||
204 | void *reg_data; /* regulator_dev data */ | 202 | void *reg_data; /* regulator_dev data */ |
205 | 203 | ||