diff options
author | Mark Brown <broonie@opensource.wolfsonmicro.com> | 2012-03-18 17:38:28 -0400 |
---|---|---|
committer | Mark Brown <broonie@opensource.wolfsonmicro.com> | 2012-03-18 17:38:28 -0400 |
commit | c02f935f5f646fe1b5dbcd909e9d09c3a912914e (patch) | |
tree | 8ee7e852c33aa37dae186c89d4a9ed518be4e5fb /drivers | |
parent | c592c761a36286ab83451daa37a21c8558ea99c0 (diff) | |
parent | c1432b1ebc684890ac81915695617ff4adfec357 (diff) |
Merge remote-tracking branches 'regulator/topic/devm' and 'regulator/topic/stub' into regulator-next
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/regulator/core.c | 108 |
1 files changed, 108 insertions, 0 deletions
diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index 8f11d0eb59a5..f4d31830f12b 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c | |||
@@ -1316,6 +1316,40 @@ struct regulator *regulator_get(struct device *dev, const char *id) | |||
1316 | } | 1316 | } |
1317 | EXPORT_SYMBOL_GPL(regulator_get); | 1317 | EXPORT_SYMBOL_GPL(regulator_get); |
1318 | 1318 | ||
1319 | static void devm_regulator_release(struct device *dev, void *res) | ||
1320 | { | ||
1321 | regulator_put(*(struct regulator **)res); | ||
1322 | } | ||
1323 | |||
1324 | /** | ||
1325 | * devm_regulator_get - Resource managed regulator_get() | ||
1326 | * @dev: device for regulator "consumer" | ||
1327 | * @id: Supply name or regulator ID. | ||
1328 | * | ||
1329 | * Managed regulator_get(). Regulators returned from this function are | ||
1330 | * automatically regulator_put() on driver detach. See regulator_get() for more | ||
1331 | * information. | ||
1332 | */ | ||
1333 | struct regulator *devm_regulator_get(struct device *dev, const char *id) | ||
1334 | { | ||
1335 | struct regulator **ptr, *regulator; | ||
1336 | |||
1337 | ptr = devres_alloc(devm_regulator_release, sizeof(*ptr), GFP_KERNEL); | ||
1338 | if (!ptr) | ||
1339 | return ERR_PTR(-ENOMEM); | ||
1340 | |||
1341 | regulator = regulator_get(dev, id); | ||
1342 | if (!IS_ERR(regulator)) { | ||
1343 | *ptr = regulator; | ||
1344 | devres_add(dev, ptr); | ||
1345 | } else { | ||
1346 | devres_free(ptr); | ||
1347 | } | ||
1348 | |||
1349 | return regulator; | ||
1350 | } | ||
1351 | EXPORT_SYMBOL_GPL(devm_regulator_get); | ||
1352 | |||
1319 | /** | 1353 | /** |
1320 | * regulator_get_exclusive - obtain exclusive access to a regulator. | 1354 | * regulator_get_exclusive - obtain exclusive access to a regulator. |
1321 | * @dev: device for regulator "consumer" | 1355 | * @dev: device for regulator "consumer" |
@@ -1381,6 +1415,34 @@ void regulator_put(struct regulator *regulator) | |||
1381 | } | 1415 | } |
1382 | EXPORT_SYMBOL_GPL(regulator_put); | 1416 | EXPORT_SYMBOL_GPL(regulator_put); |
1383 | 1417 | ||
1418 | static int devm_regulator_match(struct device *dev, void *res, void *data) | ||
1419 | { | ||
1420 | struct regulator **r = res; | ||
1421 | if (!r || !*r) { | ||
1422 | WARN_ON(!r || !*r); | ||
1423 | return 0; | ||
1424 | } | ||
1425 | return *r == data; | ||
1426 | } | ||
1427 | |||
1428 | /** | ||
1429 | * devm_regulator_put - Resource managed regulator_put() | ||
1430 | * @regulator: regulator to free | ||
1431 | * | ||
1432 | * Deallocate a regulator allocated with devm_regulator_get(). Normally | ||
1433 | * this function will not need to be called and the resource management | ||
1434 | * code will ensure that the resource is freed. | ||
1435 | */ | ||
1436 | void devm_regulator_put(struct regulator *regulator) | ||
1437 | { | ||
1438 | int rc; | ||
1439 | |||
1440 | rc = devres_destroy(regulator->dev, devm_regulator_release, | ||
1441 | devm_regulator_match, regulator); | ||
1442 | WARN_ON(rc); | ||
1443 | } | ||
1444 | EXPORT_SYMBOL_GPL(devm_regulator_put); | ||
1445 | |||
1384 | static int _regulator_can_change_status(struct regulator_dev *rdev) | 1446 | static int _regulator_can_change_status(struct regulator_dev *rdev) |
1385 | { | 1447 | { |
1386 | if (!rdev->constraints) | 1448 | if (!rdev->constraints) |
@@ -2399,6 +2461,52 @@ err: | |||
2399 | } | 2461 | } |
2400 | EXPORT_SYMBOL_GPL(regulator_bulk_get); | 2462 | EXPORT_SYMBOL_GPL(regulator_bulk_get); |
2401 | 2463 | ||
2464 | /** | ||
2465 | * devm_regulator_bulk_get - managed get multiple regulator consumers | ||
2466 | * | ||
2467 | * @dev: Device to supply | ||
2468 | * @num_consumers: Number of consumers to register | ||
2469 | * @consumers: Configuration of consumers; clients are stored here. | ||
2470 | * | ||
2471 | * @return 0 on success, an errno on failure. | ||
2472 | * | ||
2473 | * This helper function allows drivers to get several regulator | ||
2474 | * consumers in one operation with management, the regulators will | ||
2475 | * automatically be freed when the device is unbound. If any of the | ||
2476 | * regulators cannot be acquired then any regulators that were | ||
2477 | * allocated will be freed before returning to the caller. | ||
2478 | */ | ||
2479 | int devm_regulator_bulk_get(struct device *dev, int num_consumers, | ||
2480 | struct regulator_bulk_data *consumers) | ||
2481 | { | ||
2482 | int i; | ||
2483 | int ret; | ||
2484 | |||
2485 | for (i = 0; i < num_consumers; i++) | ||
2486 | consumers[i].consumer = NULL; | ||
2487 | |||
2488 | for (i = 0; i < num_consumers; i++) { | ||
2489 | consumers[i].consumer = devm_regulator_get(dev, | ||
2490 | consumers[i].supply); | ||
2491 | if (IS_ERR(consumers[i].consumer)) { | ||
2492 | ret = PTR_ERR(consumers[i].consumer); | ||
2493 | dev_err(dev, "Failed to get supply '%s': %d\n", | ||
2494 | consumers[i].supply, ret); | ||
2495 | consumers[i].consumer = NULL; | ||
2496 | goto err; | ||
2497 | } | ||
2498 | } | ||
2499 | |||
2500 | return 0; | ||
2501 | |||
2502 | err: | ||
2503 | for (i = 0; i < num_consumers && consumers[i].consumer; i++) | ||
2504 | devm_regulator_put(consumers[i].consumer); | ||
2505 | |||
2506 | return ret; | ||
2507 | } | ||
2508 | EXPORT_SYMBOL_GPL(devm_regulator_bulk_get); | ||
2509 | |||
2402 | static void regulator_bulk_enable_async(void *data, async_cookie_t cookie) | 2510 | static void regulator_bulk_enable_async(void *data, async_cookie_t cookie) |
2403 | { | 2511 | { |
2404 | struct regulator_bulk_data *bulk = data; | 2512 | struct regulator_bulk_data *bulk = data; |