aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/regulator/core.c170
-rw-r--r--drivers/regulator/devres.c163
-rw-r--r--include/linux/regulator/consumer.h79
3 files changed, 412 insertions, 0 deletions
diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c
index 906deb7354ed..16427de56ce8 100644
--- a/drivers/regulator/core.c
+++ b/drivers/regulator/core.c
@@ -53,6 +53,7 @@ static DEFINE_MUTEX(regulator_list_mutex);
53static LIST_HEAD(regulator_list); 53static LIST_HEAD(regulator_list);
54static LIST_HEAD(regulator_map_list); 54static LIST_HEAD(regulator_map_list);
55static LIST_HEAD(regulator_ena_gpio_list); 55static LIST_HEAD(regulator_ena_gpio_list);
56static LIST_HEAD(regulator_supply_alias_list);
56static bool has_full_constraints; 57static bool has_full_constraints;
57static bool board_wants_dummy_regulator; 58static bool board_wants_dummy_regulator;
58 59
@@ -83,6 +84,19 @@ struct regulator_enable_gpio {
83 unsigned int ena_gpio_invert:1; 84 unsigned int ena_gpio_invert:1;
84}; 85};
85 86
87/*
88 * struct regulator_supply_alias
89 *
90 * Used to map lookups for a supply onto an alternative device.
91 */
92struct regulator_supply_alias {
93 struct list_head list;
94 struct device *src_dev;
95 const char *src_supply;
96 struct device *alias_dev;
97 const char *alias_supply;
98};
99
86static int _regulator_is_enabled(struct regulator_dev *rdev); 100static int _regulator_is_enabled(struct regulator_dev *rdev);
87static int _regulator_disable(struct regulator_dev *rdev); 101static int _regulator_disable(struct regulator_dev *rdev);
88static int _regulator_get_voltage(struct regulator_dev *rdev); 102static int _regulator_get_voltage(struct regulator_dev *rdev);
@@ -1173,6 +1187,32 @@ static int _regulator_get_enable_time(struct regulator_dev *rdev)
1173 return rdev->desc->ops->enable_time(rdev); 1187 return rdev->desc->ops->enable_time(rdev);
1174} 1188}
1175 1189
1190static struct regulator_supply_alias *regulator_find_supply_alias(
1191 struct device *dev, const char *supply)
1192{
1193 struct regulator_supply_alias *map;
1194
1195 list_for_each_entry(map, &regulator_supply_alias_list, list)
1196 if (map->src_dev == dev && strcmp(map->src_supply, supply) == 0)
1197 return map;
1198
1199 return NULL;
1200}
1201
1202static void regulator_supply_alias(struct device **dev, const char **supply)
1203{
1204 struct regulator_supply_alias *map;
1205
1206 map = regulator_find_supply_alias(*dev, *supply);
1207 if (map) {
1208 dev_dbg(*dev, "Mapping supply %s to %s,%s\n",
1209 *supply, map->alias_supply,
1210 dev_name(map->alias_dev));
1211 *dev = map->alias_dev;
1212 *supply = map->alias_supply;
1213 }
1214}
1215
1176static struct regulator_dev *regulator_dev_lookup(struct device *dev, 1216static struct regulator_dev *regulator_dev_lookup(struct device *dev,
1177 const char *supply, 1217 const char *supply,
1178 int *ret) 1218 int *ret)
@@ -1182,6 +1222,8 @@ static struct regulator_dev *regulator_dev_lookup(struct device *dev,
1182 struct regulator_map *map; 1222 struct regulator_map *map;
1183 const char *devname = NULL; 1223 const char *devname = NULL;
1184 1224
1225 regulator_supply_alias(&dev, &supply);
1226
1185 /* first do a dt based lookup */ 1227 /* first do a dt based lookup */
1186 if (dev && dev->of_node) { 1228 if (dev && dev->of_node) {
1187 node = of_get_regulator(dev, supply); 1229 node = of_get_regulator(dev, supply);
@@ -1432,6 +1474,134 @@ void regulator_put(struct regulator *regulator)
1432} 1474}
1433EXPORT_SYMBOL_GPL(regulator_put); 1475EXPORT_SYMBOL_GPL(regulator_put);
1434 1476
1477/**
1478 * regulator_register_supply_alias - Provide device alias for supply lookup
1479 *
1480 * @dev: device that will be given as the regulator "consumer"
1481 * @id: Supply name or regulator ID
1482 * @alias_dev: device that should be used to lookup the supply
1483 * @alias_id: Supply name or regulator ID that should be used to lookup the
1484 * supply
1485 *
1486 * All lookups for id on dev will instead be conducted for alias_id on
1487 * alias_dev.
1488 */
1489int regulator_register_supply_alias(struct device *dev, const char *id,
1490 struct device *alias_dev,
1491 const char *alias_id)
1492{
1493 struct regulator_supply_alias *map;
1494
1495 map = regulator_find_supply_alias(dev, id);
1496 if (map)
1497 return -EEXIST;
1498
1499 map = kzalloc(sizeof(struct regulator_supply_alias), GFP_KERNEL);
1500 if (!map)
1501 return -ENOMEM;
1502
1503 map->src_dev = dev;
1504 map->src_supply = id;
1505 map->alias_dev = alias_dev;
1506 map->alias_supply = alias_id;
1507
1508 list_add(&map->list, &regulator_supply_alias_list);
1509
1510 pr_info("Adding alias for supply %s,%s -> %s,%s\n",
1511 id, dev_name(dev), alias_id, dev_name(alias_dev));
1512
1513 return 0;
1514}
1515EXPORT_SYMBOL_GPL(regulator_register_supply_alias);
1516
1517/**
1518 * regulator_unregister_supply_alias - Remove device alias
1519 *
1520 * @dev: device that will be given as the regulator "consumer"
1521 * @id: Supply name or regulator ID
1522 *
1523 * Remove a lookup alias if one exists for id on dev.
1524 */
1525void regulator_unregister_supply_alias(struct device *dev, const char *id)
1526{
1527 struct regulator_supply_alias *map;
1528
1529 map = regulator_find_supply_alias(dev, id);
1530 if (map) {
1531 list_del(&map->list);
1532 kfree(map);
1533 }
1534}
1535EXPORT_SYMBOL_GPL(regulator_unregister_supply_alias);
1536
1537/**
1538 * regulator_bulk_register_supply_alias - register multiple aliases
1539 *
1540 * @dev: device that will be given as the regulator "consumer"
1541 * @id: List of supply names or regulator IDs
1542 * @alias_dev: device that should be used to lookup the supply
1543 * @alias_id: List of supply names or regulator IDs that should be used to
1544 * lookup the supply
1545 * @num_id: Number of aliases to register
1546 *
1547 * @return 0 on success, an errno on failure.
1548 *
1549 * This helper function allows drivers to register several supply
1550 * aliases in one operation. If any of the aliases cannot be
1551 * registered any aliases that were registered will be removed
1552 * before returning to the caller.
1553 */
1554int regulator_bulk_register_supply_alias(struct device *dev, const char **id,
1555 struct device *alias_dev,
1556 const char **alias_id,
1557 int num_id)
1558{
1559 int i;
1560 int ret;
1561
1562 for (i = 0; i < num_id; ++i) {
1563 ret = regulator_register_supply_alias(dev, id[i], alias_dev,
1564 alias_id[i]);
1565 if (ret < 0)
1566 goto err;
1567 }
1568
1569 return 0;
1570
1571err:
1572 dev_err(dev,
1573 "Failed to create supply alias %s,%s -> %s,%s\n",
1574 id[i], dev_name(dev), alias_id[i], dev_name(alias_dev));
1575
1576 while (--i >= 0)
1577 regulator_unregister_supply_alias(dev, id[i]);
1578
1579 return ret;
1580}
1581EXPORT_SYMBOL_GPL(regulator_bulk_register_supply_alias);
1582
1583/**
1584 * regulator_bulk_unregister_supply_alias - unregister multiple aliases
1585 *
1586 * @dev: device that will be given as the regulator "consumer"
1587 * @id: List of supply names or regulator IDs
1588 * @num_id: Number of aliases to unregister
1589 *
1590 * This helper function allows drivers to unregister several supply
1591 * aliases in one operation.
1592 */
1593void regulator_bulk_unregister_supply_alias(struct device *dev,
1594 const char **id,
1595 int num_id)
1596{
1597 int i;
1598
1599 for (i = 0; i < num_id; ++i)
1600 regulator_unregister_supply_alias(dev, id[i]);
1601}
1602EXPORT_SYMBOL_GPL(regulator_bulk_unregister_supply_alias);
1603
1604
1435/* Manage enable GPIO list. Same GPIO pin can be shared among regulators */ 1605/* Manage enable GPIO list. Same GPIO pin can be shared among regulators */
1436static int regulator_ena_gpio_request(struct regulator_dev *rdev, 1606static int regulator_ena_gpio_request(struct regulator_dev *rdev,
1437 const struct regulator_config *config) 1607 const struct regulator_config *config)
diff --git a/drivers/regulator/devres.c b/drivers/regulator/devres.c
index 2672a029fa25..f44818b838dc 100644
--- a/drivers/regulator/devres.c
+++ b/drivers/regulator/devres.c
@@ -250,3 +250,166 @@ void devm_regulator_unregister(struct device *dev, struct regulator_dev *rdev)
250 WARN_ON(rc); 250 WARN_ON(rc);
251} 251}
252EXPORT_SYMBOL_GPL(devm_regulator_unregister); 252EXPORT_SYMBOL_GPL(devm_regulator_unregister);
253
254struct regulator_supply_alias_match {
255 struct device *dev;
256 const char *id;
257};
258
259static int devm_regulator_match_supply_alias(struct device *dev, void *res,
260 void *data)
261{
262 struct regulator_supply_alias_match *match = res;
263 struct regulator_supply_alias_match *target = data;
264
265 return match->dev == target->dev && strcmp(match->id, target->id) == 0;
266}
267
268static void devm_regulator_destroy_supply_alias(struct device *dev, void *res)
269{
270 struct regulator_supply_alias_match *match = res;
271
272 regulator_unregister_supply_alias(match->dev, match->id);
273}
274
275/**
276 * devm_regulator_register_supply_alias - Resource managed
277 * regulator_register_supply_alias()
278 *
279 * @dev: device that will be given as the regulator "consumer"
280 * @id: Supply name or regulator ID
281 * @alias_dev: device that should be used to lookup the supply
282 * @alias_id: Supply name or regulator ID that should be used to lookup the
283 * supply
284 *
285 * The supply alias will automatically be unregistered when the source
286 * device is unbound.
287 */
288int devm_regulator_register_supply_alias(struct device *dev, const char *id,
289 struct device *alias_dev,
290 const char *alias_id)
291{
292 struct regulator_supply_alias_match *match;
293 int ret;
294
295 match = devres_alloc(devm_regulator_destroy_supply_alias,
296 sizeof(struct regulator_supply_alias_match),
297 GFP_KERNEL);
298 if (!match)
299 return -ENOMEM;
300
301 match->dev = dev;
302 match->id = id;
303
304 ret = regulator_register_supply_alias(dev, id, alias_dev, alias_id);
305 if (ret < 0) {
306 devres_free(match);
307 return ret;
308 }
309
310 devres_add(dev, match);
311
312 return 0;
313}
314EXPORT_SYMBOL_GPL(devm_regulator_register_supply_alias);
315
316/**
317 * devm_regulator_unregister_supply_alias - Resource managed
318 * regulator_unregister_supply_alias()
319 *
320 * @dev: device that will be given as the regulator "consumer"
321 * @id: Supply name or regulator ID
322 *
323 * Unregister an alias registered with
324 * devm_regulator_register_supply_alias(). Normally this function
325 * will not need to be called and the resource management code
326 * will ensure that the resource is freed.
327 */
328void devm_regulator_unregister_supply_alias(struct device *dev, const char *id)
329{
330 struct regulator_supply_alias_match match;
331 int rc;
332
333 match.dev = dev;
334 match.id = id;
335
336 rc = devres_release(dev, devm_regulator_destroy_supply_alias,
337 devm_regulator_match_supply_alias, &match);
338 if (rc != 0)
339 WARN_ON(rc);
340}
341EXPORT_SYMBOL_GPL(devm_regulator_unregister_supply_alias);
342
343/**
344 * devm_regulator_bulk_register_supply_alias - Managed register
345 * multiple aliases
346 *
347 * @dev: device that will be given as the regulator "consumer"
348 * @id: List of supply names or regulator IDs
349 * @alias_dev: device that should be used to lookup the supply
350 * @alias_id: List of supply names or regulator IDs that should be used to
351 * lookup the supply
352 * @num_id: Number of aliases to register
353 *
354 * @return 0 on success, an errno on failure.
355 *
356 * This helper function allows drivers to register several supply
357 * aliases in one operation, the aliases will be automatically
358 * unregisters when the source device is unbound. If any of the
359 * aliases cannot be registered any aliases that were registered
360 * will be removed before returning to the caller.
361 */
362int devm_regulator_bulk_register_supply_alias(struct device *dev,
363 const char **id,
364 struct device *alias_dev,
365 const char **alias_id,
366 int num_id)
367{
368 int i;
369 int ret;
370
371 for (i = 0; i < num_id; ++i) {
372 ret = devm_regulator_register_supply_alias(dev, id[i],
373 alias_dev,
374 alias_id[i]);
375 if (ret < 0)
376 goto err;
377 }
378
379 return 0;
380
381err:
382 dev_err(dev,
383 "Failed to create supply alias %s,%s -> %s,%s\n",
384 id[i], dev_name(dev), alias_id[i], dev_name(alias_dev));
385
386 while (--i >= 0)
387 devm_regulator_unregister_supply_alias(dev, id[i]);
388
389 return ret;
390}
391EXPORT_SYMBOL_GPL(devm_regulator_bulk_register_supply_alias);
392
393/**
394 * devm_regulator_bulk_unregister_supply_alias - Managed unregister
395 * multiple aliases
396 *
397 * @dev: device that will be given as the regulator "consumer"
398 * @id: List of supply names or regulator IDs
399 * @num_id: Number of aliases to unregister
400 *
401 * Unregister aliases registered with
402 * devm_regulator_bulk_register_supply_alias(). Normally this function
403 * will not need to be called and the resource management code
404 * will ensure that the resource is freed.
405 */
406void devm_regulator_bulk_unregister_supply_alias(struct device *dev,
407 const char **id,
408 int num_id)
409{
410 int i;
411
412 for (i = 0; i < num_id; ++i)
413 devm_regulator_unregister_supply_alias(dev, id[i]);
414}
415EXPORT_SYMBOL_GPL(devm_regulator_bulk_unregister_supply_alias);
diff --git a/include/linux/regulator/consumer.h b/include/linux/regulator/consumer.h
index 27be915caa96..e530681bea70 100644
--- a/include/linux/regulator/consumer.h
+++ b/include/linux/regulator/consumer.h
@@ -146,6 +146,32 @@ struct regulator *__must_check devm_regulator_get_optional(struct device *dev,
146void regulator_put(struct regulator *regulator); 146void regulator_put(struct regulator *regulator);
147void devm_regulator_put(struct regulator *regulator); 147void devm_regulator_put(struct regulator *regulator);
148 148
149int regulator_register_supply_alias(struct device *dev, const char *id,
150 struct device *alias_dev,
151 const char *alias_id);
152void regulator_unregister_supply_alias(struct device *dev, const char *id);
153
154int regulator_bulk_register_supply_alias(struct device *dev, const char **id,
155 struct device *alias_dev,
156 const char **alias_id, int num_id);
157void regulator_bulk_unregister_supply_alias(struct device *dev,
158 const char **id, int num_id);
159
160int devm_regulator_register_supply_alias(struct device *dev, const char *id,
161 struct device *alias_dev,
162 const char *alias_id);
163void devm_regulator_unregister_supply_alias(struct device *dev,
164 const char *id);
165
166int devm_regulator_bulk_register_supply_alias(struct device *dev,
167 const char **id,
168 struct device *alias_dev,
169 const char **alias_id,
170 int num_id);
171void devm_regulator_bulk_unregister_supply_alias(struct device *dev,
172 const char **id,
173 int num_id);
174
149/* regulator output control and status */ 175/* regulator output control and status */
150int __must_check regulator_enable(struct regulator *regulator); 176int __must_check regulator_enable(struct regulator *regulator);
151int regulator_disable(struct regulator *regulator); 177int regulator_disable(struct regulator *regulator);
@@ -250,6 +276,59 @@ static inline void devm_regulator_put(struct regulator *regulator)
250{ 276{
251} 277}
252 278
279static inline int regulator_register_supply_alias(struct device *dev,
280 const char *id,
281 struct device *alias_dev,
282 const char *alias_id)
283{
284 return 0;
285}
286
287static inline void regulator_unregister_supply_alias(struct device *dev,
288 const char *id)
289{
290}
291
292static inline int regulator_bulk_register_supply_alias(struct device *dev,
293 const char **id,
294 struct device *alias_dev,
295 const char **alias_id,
296 int num_id)
297{
298 return 0;
299}
300
301static inline void regulator_bulk_unregister_supply_alias(struct device *dev,
302 const char **id,
303 int num_id)
304{
305}
306
307static inline int devm_regulator_register_supply_alias(struct device *dev,
308 const char *id,
309 struct device *alias_dev,
310 const char *alias_id)
311{
312 return 0;
313}
314
315static inline void devm_regulator_unregister_supply_alias(struct device *dev,
316 const char *id)
317{
318}
319
320static inline int devm_regulator_bulk_register_supply_alias(
321 struct device *dev, const char **id, struct device *alias_dev,
322 const char **alias_id, int num_id)
323{
324 return 0;
325}
326
327static inline void devm_regulator_bulk_unregister_supply_alias(
328 struct device *dev, const char **id, int num_id)
329{
330}
331
253static inline int regulator_enable(struct regulator *regulator) 332static inline int regulator_enable(struct regulator *regulator)
254{ 333{
255 return 0; 334 return 0;