Skip to content

Commit db6f6ba

Browse files
committed
regulator: Add of_regulator_bulk_get_all()
Merge series from Corentin Labbe <[email protected]>: This adds a new regulator_bulk_get_all() which grab all supplies properties in a DT node, for use in implementing generic handling for things like MDIO PHYs where the physical standardisation of the bus does not extend to power supplies.
2 parents bc64f30 + 27b9ecc commit db6f6ba

File tree

2 files changed

+100
-0
lines changed

2 files changed

+100
-0
lines changed

drivers/regulator/of_regulator.c

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -701,3 +701,95 @@ struct regulator_dev *of_parse_coupled_regulator(struct regulator_dev *rdev,
701701

702702
return c_rdev;
703703
}
704+
705+
/*
706+
* Check if name is a supply name according to the '*-supply' pattern
707+
* return 0 if false
708+
* return length of supply name without the -supply
709+
*/
710+
static int is_supply_name(const char *name)
711+
{
712+
int strs, i;
713+
714+
strs = strlen(name);
715+
/* string need to be at minimum len(x-supply) */
716+
if (strs < 8)
717+
return 0;
718+
for (i = strs - 6; i > 0; i--) {
719+
/* find first '-' and check if right part is supply */
720+
if (name[i] != '-')
721+
continue;
722+
if (strcmp(name + i + 1, "supply") != 0)
723+
return 0;
724+
return i;
725+
}
726+
return 0;
727+
}
728+
729+
/*
730+
* of_regulator_bulk_get_all - get multiple regulator consumers
731+
*
732+
* @dev: Device to supply
733+
* @np: device node to search for consumers
734+
* @consumers: Configuration of consumers; clients are stored here.
735+
*
736+
* @return number of regulators on success, an errno on failure.
737+
*
738+
* This helper function allows drivers to get several regulator
739+
* consumers in one operation. If any of the regulators cannot be
740+
* acquired then any regulators that were allocated will be freed
741+
* before returning to the caller.
742+
*/
743+
int of_regulator_bulk_get_all(struct device *dev, struct device_node *np,
744+
struct regulator_bulk_data **consumers)
745+
{
746+
int num_consumers = 0;
747+
struct regulator *tmp;
748+
struct property *prop;
749+
int i, n = 0, ret;
750+
char name[64];
751+
752+
*consumers = NULL;
753+
754+
/*
755+
* first pass: get numbers of xxx-supply
756+
* second pass: fill consumers
757+
*/
758+
restart:
759+
for_each_property_of_node(np, prop) {
760+
i = is_supply_name(prop->name);
761+
if (i == 0)
762+
continue;
763+
if (!*consumers) {
764+
num_consumers++;
765+
continue;
766+
} else {
767+
memcpy(name, prop->name, i);
768+
name[i] = '\0';
769+
tmp = regulator_get(dev, name);
770+
if (!tmp) {
771+
ret = -EINVAL;
772+
goto error;
773+
}
774+
(*consumers)[n].consumer = tmp;
775+
n++;
776+
continue;
777+
}
778+
}
779+
if (*consumers)
780+
return num_consumers;
781+
if (num_consumers == 0)
782+
return 0;
783+
*consumers = kmalloc_array(num_consumers,
784+
sizeof(struct regulator_bulk_data),
785+
GFP_KERNEL);
786+
if (!*consumers)
787+
return -ENOMEM;
788+
goto restart;
789+
790+
error:
791+
while (--n >= 0)
792+
regulator_put(consumers[n]->consumer);
793+
return ret;
794+
}
795+
EXPORT_SYMBOL_GPL(of_regulator_bulk_get_all);

include/linux/regulator/consumer.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -244,6 +244,8 @@ int regulator_disable_deferred(struct regulator *regulator, int ms);
244244

245245
int __must_check regulator_bulk_get(struct device *dev, int num_consumers,
246246
struct regulator_bulk_data *consumers);
247+
int __must_check of_regulator_bulk_get_all(struct device *dev, struct device_node *np,
248+
struct regulator_bulk_data **consumers);
247249
int __must_check devm_regulator_bulk_get(struct device *dev, int num_consumers,
248250
struct regulator_bulk_data *consumers);
249251
void devm_regulator_bulk_put(struct regulator_bulk_data *consumers);
@@ -481,6 +483,12 @@ static inline int devm_regulator_bulk_get(struct device *dev, int num_consumers,
481483
return 0;
482484
}
483485

486+
static inline int of_regulator_bulk_get_all(struct device *dev, struct device_node *np,
487+
struct regulator_bulk_data **consumers)
488+
{
489+
return 0;
490+
}
491+
484492
static inline int regulator_bulk_enable(int num_consumers,
485493
struct regulator_bulk_data *consumers)
486494
{

0 commit comments

Comments
 (0)