mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-10-03 15:47:36 +00:00
regulator: Add of_regulator_bulk_get_all
It work exactly like regulator_bulk_get() but instead of working on a provided list of names, it seek all consumers properties matching xxx-supply. Signed-off-by: Corentin Labbe <clabbe@baylibre.com> Link: https://lore.kernel.org/r/20221115073603.3425396-2-clabbe@baylibre.com Signed-off-by: Mark Brown <broonie@kernel.org>
This commit is contained in:
parent
9abf2313ad
commit
27b9ecc7a9
2 changed files with 100 additions and 0 deletions
|
@ -701,3 +701,95 @@ struct regulator_dev *of_parse_coupled_regulator(struct regulator_dev *rdev,
|
||||||
|
|
||||||
return c_rdev;
|
return c_rdev;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Check if name is a supply name according to the '*-supply' pattern
|
||||||
|
* return 0 if false
|
||||||
|
* return length of supply name without the -supply
|
||||||
|
*/
|
||||||
|
static int is_supply_name(const char *name)
|
||||||
|
{
|
||||||
|
int strs, i;
|
||||||
|
|
||||||
|
strs = strlen(name);
|
||||||
|
/* string need to be at minimum len(x-supply) */
|
||||||
|
if (strs < 8)
|
||||||
|
return 0;
|
||||||
|
for (i = strs - 6; i > 0; i--) {
|
||||||
|
/* find first '-' and check if right part is supply */
|
||||||
|
if (name[i] != '-')
|
||||||
|
continue;
|
||||||
|
if (strcmp(name + i + 1, "supply") != 0)
|
||||||
|
return 0;
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* of_regulator_bulk_get_all - get multiple regulator consumers
|
||||||
|
*
|
||||||
|
* @dev: Device to supply
|
||||||
|
* @np: device node to search for consumers
|
||||||
|
* @consumers: Configuration of consumers; clients are stored here.
|
||||||
|
*
|
||||||
|
* @return number of regulators on success, an errno on failure.
|
||||||
|
*
|
||||||
|
* This helper function allows drivers to get several regulator
|
||||||
|
* consumers in one operation. If any of the regulators cannot be
|
||||||
|
* acquired then any regulators that were allocated will be freed
|
||||||
|
* before returning to the caller.
|
||||||
|
*/
|
||||||
|
int of_regulator_bulk_get_all(struct device *dev, struct device_node *np,
|
||||||
|
struct regulator_bulk_data **consumers)
|
||||||
|
{
|
||||||
|
int num_consumers = 0;
|
||||||
|
struct regulator *tmp;
|
||||||
|
struct property *prop;
|
||||||
|
int i, n = 0, ret;
|
||||||
|
char name[64];
|
||||||
|
|
||||||
|
*consumers = NULL;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* first pass: get numbers of xxx-supply
|
||||||
|
* second pass: fill consumers
|
||||||
|
*/
|
||||||
|
restart:
|
||||||
|
for_each_property_of_node(np, prop) {
|
||||||
|
i = is_supply_name(prop->name);
|
||||||
|
if (i == 0)
|
||||||
|
continue;
|
||||||
|
if (!*consumers) {
|
||||||
|
num_consumers++;
|
||||||
|
continue;
|
||||||
|
} else {
|
||||||
|
memcpy(name, prop->name, i);
|
||||||
|
name[i] = '\0';
|
||||||
|
tmp = regulator_get(dev, name);
|
||||||
|
if (!tmp) {
|
||||||
|
ret = -EINVAL;
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
(*consumers)[n].consumer = tmp;
|
||||||
|
n++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (*consumers)
|
||||||
|
return num_consumers;
|
||||||
|
if (num_consumers == 0)
|
||||||
|
return 0;
|
||||||
|
*consumers = kmalloc_array(num_consumers,
|
||||||
|
sizeof(struct regulator_bulk_data),
|
||||||
|
GFP_KERNEL);
|
||||||
|
if (!*consumers)
|
||||||
|
return -ENOMEM;
|
||||||
|
goto restart;
|
||||||
|
|
||||||
|
error:
|
||||||
|
while (--n >= 0)
|
||||||
|
regulator_put(consumers[n]->consumer);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL_GPL(of_regulator_bulk_get_all);
|
||||||
|
|
|
@ -244,6 +244,8 @@ int regulator_disable_deferred(struct regulator *regulator, int ms);
|
||||||
|
|
||||||
int __must_check regulator_bulk_get(struct device *dev, int num_consumers,
|
int __must_check regulator_bulk_get(struct device *dev, int num_consumers,
|
||||||
struct regulator_bulk_data *consumers);
|
struct regulator_bulk_data *consumers);
|
||||||
|
int __must_check of_regulator_bulk_get_all(struct device *dev, struct device_node *np,
|
||||||
|
struct regulator_bulk_data **consumers);
|
||||||
int __must_check devm_regulator_bulk_get(struct device *dev, int num_consumers,
|
int __must_check devm_regulator_bulk_get(struct device *dev, int num_consumers,
|
||||||
struct regulator_bulk_data *consumers);
|
struct regulator_bulk_data *consumers);
|
||||||
void devm_regulator_bulk_put(struct regulator_bulk_data *consumers);
|
void devm_regulator_bulk_put(struct regulator_bulk_data *consumers);
|
||||||
|
@ -479,6 +481,12 @@ static inline int devm_regulator_bulk_get(struct device *dev, int num_consumers,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline int of_regulator_bulk_get_all(struct device *dev, struct device_node *np,
|
||||||
|
struct regulator_bulk_data **consumers)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static inline int regulator_bulk_enable(int num_consumers,
|
static inline int regulator_bulk_enable(int num_consumers,
|
||||||
struct regulator_bulk_data *consumers)
|
struct regulator_bulk_data *consumers)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue