// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * OF helpers for regulator framework
 *
 * Copyright (C) 2011 Texas Instruments, Inc.
 * Rajendra Nayak <rnayak@ti.com>
 */

#include <linux/module.h>
#include <linux/slab.h>
#include <linux/of.h>
#include <linux/regulator/machine.h>
#include <linux/regulator/driver.h>
#include <linux/regulator/of_regulator.h>

#include "internal.h"

static const char *const regulator_states[PM_SUSPEND_MAX + 1] = {
	[PM_SUSPEND_STANDBY]	= "regulator-state-standby",
	[PM_SUSPEND_MEM]	= "regulator-state-mem",
	[PM_SUSPEND_MAX]	= "regulator-state-disk",
};

static void fill_limit(int *limit, int val)
{
	if (val)
		if (val == 1)
			*limit = REGULATOR_NOTIF_LIMIT_ENABLE;
		else
			*limit = val;
	else
		*limit = REGULATOR_NOTIF_LIMIT_DISABLE;
}

static void of_get_regulator_prot_limits(struct device_node *np,
				struct regulation_constraints *constraints)
{
	u32 pval;
	int i;
	static const char *const props[] = {
		"regulator-oc-%s-microamp",
		"regulator-ov-%s-microvolt",
		"regulator-temp-%s-kelvin",
		"regulator-uv-%s-microvolt",
	};
	struct notification_limit *limits[] = {
		&constraints->over_curr_limits,
		&constraints->over_voltage_limits,
		&constraints->temp_limits,
		&constraints->under_voltage_limits,
	};
	bool set[4] = {0};

	/* Protection limits: */
	for (i = 0; i < ARRAY_SIZE(props); i++) {
		char prop[255];
		bool found;
		int j;
		static const char *const lvl[] = {
			"protection", "error", "warn"
		};
		int *l[] = {
			&limits[i]->prot, &limits[i]->err, &limits[i]->warn,
		};

		for (j = 0; j < ARRAY_SIZE(lvl); j++) {
			snprintf(prop, 255, props[i], lvl[j]);
			found = !of_property_read_u32(np, prop, &pval);
			if (found)
				fill_limit(l[j], pval);
			set[i] |= found;
		}
	}
	constraints->over_current_detection = set[0];
	constraints->over_voltage_detection = set[1];
	constraints->over_temp_detection = set[2];
	constraints->under_voltage_detection = set[3];
}

static int of_get_regulation_constraints(struct device *dev,
					struct device_node *np,
					struct regulator_init_data **init_data,
					const struct regulator_desc *desc)
{
	struct regulation_constraints *constraints = &(*init_data)->constraints;
	struct regulator_state *suspend_state;
	struct device_node *suspend_np;
	unsigned int mode;
	int ret, i, len;
	int n_phandles;
	u32 pval;

	n_phandles = of_count_phandle_with_args(np, "regulator-coupled-with",
						NULL);
	n_phandles = max(n_phandles, 0);

	constraints->name = of_get_property(np, "regulator-name", NULL);

	if (!of_property_read_u32(np, "regulator-min-microvolt", &pval))
		constraints->min_uV = pval;

	if (!of_property_read_u32(np, "regulator-max-microvolt", &pval))
		constraints->max_uV = pval;

	/* Voltage change possible? */
	if (constraints->min_uV != constraints->max_uV)
		constraints->valid_ops_mask |= REGULATOR_CHANGE_VOLTAGE;

	/* Do we have a voltage range, if so try to apply it? */
	if (constraints->min_uV && constraints->max_uV)
		constraints->apply_uV = true;

	if (!of_property_read_u32(np, "regulator-microvolt-offset", &pval))
		constraints->uV_offset = pval;
	if (!of_property_read_u32(np, "regulator-min-microamp", &pval))
		constraints->min_uA = pval;
	if (!of_property_read_u32(np, "regulator-max-microamp", &pval))
		constraints->max_uA = pval;

	if (!of_property_read_u32(np, "regulator-input-current-limit-microamp",
				  &pval))
		constraints->ilim_uA = pval;

	/* Current change possible? */
	if (constraints->min_uA != constraints->max_uA)
		constraints->valid_ops_mask |= REGULATOR_CHANGE_CURRENT;

	constraints->boot_on = of_property_read_bool(np, "regulator-boot-on");
	constraints->always_on = of_property_read_bool(np, "regulator-always-on");
	if (!constraints->always_on) /* status change should be possible. */
		constraints->valid_ops_mask |= REGULATOR_CHANGE_STATUS;

	constraints->pull_down = of_property_read_bool(np, "regulator-pull-down");
	constraints->system_critical = of_property_read_bool(np,
						"system-critical-regulator");

	if (of_property_read_bool(np, "regulator-allow-bypass"))
		constraints->valid_ops_mask |= REGULATOR_CHANGE_BYPASS;

	if (of_property_read_bool(np, "regulator-allow-set-load"))
		constraints->valid_ops_mask |= REGULATOR_CHANGE_DRMS;

	ret = of_property_read_u32(np, "regulator-ramp-delay", &pval);
	if (!ret) {
		if (pval)
			constraints->ramp_delay = pval;
		else
			constraints->ramp_disable = true;
	}

	ret = of_property_read_u32(np, "regulator-settling-time-us", &pval);
	if (!ret)
		constraints->settling_time = pval;

	ret = of_property_read_u32(np, "regulator-settling-time-up-us", &pval);
	if (!ret)
		constraints->settling_time_up = pval;
	if (constraints->settling_time_up && constraints->settling_time) {
		pr_warn("%pOFn: ambiguous configuration for settling time, ignoring 'regulator-settling-time-up-us'\n",
			np);
		constraints->settling_time_up = 0;
	}

	ret = of_property_read_u32(np, "regulator-settling-time-down-us",
				   &pval);
	if (!ret)
		constraints->settling_time_down = pval;
	if (constraints->settling_time_down && constraints->settling_time) {
		pr_warn("%pOFn: ambiguous configuration for settling time, ignoring 'regulator-settling-time-down-us'\n",
			np);
		constraints->settling_time_down = 0;
	}

	ret = of_property_read_u32(np, "regulator-enable-ramp-delay", &pval);
	if (!ret)
		constraints->enable_time = pval;

	ret = of_property_read_u32(np, "regulator-uv-survival-time-ms", &pval);
	if (!ret)
		constraints->uv_less_critical_window_ms = pval;
	else
		constraints->uv_less_critical_window_ms =
				REGULATOR_DEF_UV_LESS_CRITICAL_WINDOW_MS;

	constraints->soft_start = of_property_read_bool(np,
					"regulator-soft-start");
	ret = of_property_read_u32(np, "regulator-active-discharge", &pval);
	if (!ret) {
		constraints->active_discharge =
				(pval) ? REGULATOR_ACTIVE_DISCHARGE_ENABLE :
					REGULATOR_ACTIVE_DISCHARGE_DISABLE;
	}

	if (!of_property_read_u32(np, "regulator-initial-mode", &pval)) {
		if (desc && desc->of_map_mode) {
			mode = desc->of_map_mode(pval);
			if (mode == REGULATOR_MODE_INVALID)
				pr_err("%pOFn: invalid mode %u\n", np, pval);
			else
				constraints->initial_mode = mode;
		} else {
			pr_warn("%pOFn: mapping for mode %d not defined\n",
				np, pval);
		}
	}

	len = of_property_count_elems_of_size(np, "regulator-allowed-modes",
						sizeof(u32));
	if (len > 0) {
		if (desc && desc->of_map_mode) {
			for (i = 0; i < len; i++) {
				ret = of_property_read_u32_index(np,
					"regulator-allowed-modes", i, &pval);
				if (ret) {
					pr_err("%pOFn: couldn't read allowed modes index %d, ret=%d\n",
						np, i, ret);
					break;
				}
				mode = desc->of_map_mode(pval);
				if (mode == REGULATOR_MODE_INVALID)
					pr_err("%pOFn: invalid regulator-allowed-modes element %u\n",
						np, pval);
				else
					constraints->valid_modes_mask |= mode;
			}
			if (constraints->valid_modes_mask)
				constraints->valid_ops_mask
					|= REGULATOR_CHANGE_MODE;
		} else {
			pr_warn("%pOFn: mode mapping not defined\n", np);
		}
	}

	if (!of_property_read_u32(np, "regulator-system-load", &pval))
		constraints->system_load = pval;

	if (n_phandles) {
		constraints->max_spread = devm_kzalloc(dev,
				sizeof(*constraints->max_spread) * n_phandles,
				GFP_KERNEL);

		if (!constraints->max_spread)
			return -ENOMEM;

		of_property_read_u32_array(np, "regulator-coupled-max-spread",
					   constraints->max_spread, n_phandles);
	}

	if (!of_property_read_u32(np, "regulator-max-step-microvolt",
				  &pval))
		constraints->max_uV_step = pval;

	constraints->over_current_protection = of_property_read_bool(np,
					"regulator-over-current-protection");

	of_get_regulator_prot_limits(np, constraints);

	for (i = 0; i < ARRAY_SIZE(regulator_states); i++) {
		switch (i) {
		case PM_SUSPEND_MEM:
			suspend_state = &constraints->state_mem;
			break;
		case PM_SUSPEND_MAX:
			suspend_state = &constraints->state_disk;
			break;
		case PM_SUSPEND_STANDBY:
			suspend_state = &constraints->state_standby;
			break;
		case PM_SUSPEND_ON:
		case PM_SUSPEND_TO_IDLE:
		default:
			continue;
		}

		suspend_np = of_get_child_by_name(np, regulator_states[i]);
		if (!suspend_np)
			continue;
		if (!suspend_state) {
			of_node_put(suspend_np);
			continue;
		}

		if (!of_property_read_u32(suspend_np, "regulator-mode",
					  &pval)) {
			if (desc && desc->of_map_mode) {
				mode = desc->of_map_mode(pval);
				if (mode == REGULATOR_MODE_INVALID)
					pr_err("%pOFn: invalid mode %u\n",
					       np, pval);
				else
					suspend_state->mode = mode;
			} else {
				pr_warn("%pOFn: mapping for mode %d not defined\n",
					np, pval);
			}
		}

		if (of_property_read_bool(suspend_np,
					"regulator-on-in-suspend"))
			suspend_state->enabled = ENABLE_IN_SUSPEND;
		else if (of_property_read_bool(suspend_np,
					"regulator-off-in-suspend"))
			suspend_state->enabled = DISABLE_IN_SUSPEND;

		if (!of_property_read_u32(suspend_np,
				"regulator-suspend-min-microvolt", &pval))
			suspend_state->min_uV = pval;

		if (!of_property_read_u32(suspend_np,
				"regulator-suspend-max-microvolt", &pval))
			suspend_state->max_uV = pval;

		if (!of_property_read_u32(suspend_np,
					"regulator-suspend-microvolt", &pval))
			suspend_state->uV = pval;
		else /* otherwise use min_uV as default suspend voltage */
			suspend_state->uV = suspend_state->min_uV;

		if (of_property_read_bool(suspend_np,
					"regulator-changeable-in-suspend"))
			suspend_state->changeable = true;

		if (i == PM_SUSPEND_MEM)
			constraints->initial_state = PM_SUSPEND_MEM;

		of_node_put(suspend_np);
		suspend_state = NULL;
		suspend_np = NULL;
	}

	return 0;
}

/**
 * of_get_regulator_init_data - extract regulator_init_data structure info
 * @dev: device requesting for regulator_init_data
 * @node: regulator device node
 * @desc: regulator description
 *
 * Populates regulator_init_data structure by extracting data from device
 * tree node.
 *
 * Return: Pointer to a populated &struct regulator_init_data or NULL if
 *	   memory allocation fails.
 */
struct regulator_init_data *of_get_regulator_init_data(struct device *dev,
					  struct device_node *node,
					  const struct regulator_desc *desc)
{
	struct regulator_init_data *init_data;

	if (!node)
		return NULL;

	init_data = devm_kzalloc(dev, sizeof(*init_data), GFP_KERNEL);
	if (!init_data)
		return NULL; /* Out of memory? */

	if (of_get_regulation_constraints(dev, node, &init_data, desc))
		return NULL;

	return init_data;
}
EXPORT_SYMBOL_GPL(of_get_regulator_init_data);

struct devm_of_regulator_matches {
	struct of_regulator_match *matches;
	unsigned int num_matches;
};

static void devm_of_regulator_put_matches(struct device *dev, void *res)
{
	struct devm_of_regulator_matches *devm_matches = res;
	int i;

	for (i = 0; i < devm_matches->num_matches; i++)
		of_node_put(devm_matches->matches[i].of_node);
}

/**
 * of_regulator_match - extract multiple regulator init data from device tree.
 * @dev: device requesting the data
 * @node: parent device node of the regulators
 * @matches: match table for the regulators
 * @num_matches: number of entries in match table
 *
 * This function uses a match table specified by the regulator driver to
 * parse regulator init data from the device tree. @node is expected to
 * contain a set of child nodes, each providing the init data for one
 * regulator. The data parsed from a child node will be matched to a regulator
 * based on either the deprecated property regulator-compatible if present,
 * or otherwise the child node's name. Note that the match table is modified
 * in place and an additional of_node reference is taken for each matched
 * regulator.
 *
 * Return: The number of matches found or a negative error number on failure.
 */
int of_regulator_match(struct device *dev, struct device_node *node,
		       struct of_regulator_match *matches,
		       unsigned int num_matches)
{
	unsigned int count = 0;
	unsigned int i;
	const char *name;
	struct device_node *child;
	struct devm_of_regulator_matches *devm_matches;

	if (!dev || !node)
		return -EINVAL;

	devm_matches = devres_alloc(devm_of_regulator_put_matches,
				    sizeof(struct devm_of_regulator_matches),
				    GFP_KERNEL);
	if (!devm_matches)
		return -ENOMEM;

	devm_matches->matches = matches;
	devm_matches->num_matches = num_matches;

	devres_add(dev, devm_matches);

	for (i = 0; i < num_matches; i++) {
		struct of_regulator_match *match = &matches[i];
		match->init_data = NULL;
		match->of_node = NULL;
	}

	for_each_child_of_node(node, child) {
		name = of_get_property(child,
					"regulator-compatible", NULL);
		if (!name)
			name = child->name;
		for (i = 0; i < num_matches; i++) {
			struct of_regulator_match *match = &matches[i];
			if (match->of_node)
				continue;

			if (strcmp(match->name, name))
				continue;

			match->init_data =
				of_get_regulator_init_data(dev, child,
							   match->desc);
			if (!match->init_data) {
				dev_err(dev,
					"failed to parse DT for regulator %pOFn\n",
					child);
				of_node_put(child);
				return -EINVAL;
			}
			match->of_node = of_node_get(child);
			count++;
			break;
		}
	}

	return count;
}
EXPORT_SYMBOL_GPL(of_regulator_match);

static struct
device_node *regulator_of_get_init_node(struct device *dev,
					const struct regulator_desc *desc)
{
	struct device_node *search, *child;
	const char *name;

	if (!dev->of_node || !desc->of_match)
		return NULL;

	if (desc->regulators_node) {
		search = of_get_child_by_name(dev->of_node,
					      desc->regulators_node);
	} else {
		search = of_node_get(dev->of_node);

		if (!strcmp(desc->of_match, search->name))
			return search;
	}

	if (!search) {
		dev_dbg(dev, "Failed to find regulator container node '%s'\n",
			desc->regulators_node);
		return NULL;
	}

	for_each_available_child_of_node(search, child) {
		name = of_get_property(child, "regulator-compatible", NULL);
		if (!name) {
			if (!desc->of_match_full_name)
				name = child->name;
			else
				name = child->full_name;
		}

		if (!strcmp(desc->of_match, name)) {
			of_node_put(search);
			/*
			 * 'of_node_get(child)' is already performed by the
			 * for_each loop.
			 */
			return child;
		}
	}

	of_node_put(search);

	return NULL;
}

struct regulator_init_data *regulator_of_get_init_data(struct device *dev,
					    const struct regulator_desc *desc,
					    struct regulator_config *config,
					    struct device_node **node)
{
	struct device_node *child;
	struct regulator_init_data *init_data = NULL;

	child = regulator_of_get_init_node(config->dev, desc);
	if (!child)
		return NULL;

	init_data = of_get_regulator_init_data(dev, child, desc);
	if (!init_data) {
		dev_err(dev, "failed to parse DT for regulator %pOFn\n", child);
		goto error;
	}

	if (desc->of_parse_cb) {
		int ret;

		ret = desc->of_parse_cb(child, desc, config);
		if (ret) {
			if (ret == -EPROBE_DEFER) {
				of_node_put(child);
				return ERR_PTR(-EPROBE_DEFER);
			}
			dev_err(dev,
				"driver callback failed to parse DT for regulator %pOFn\n",
				child);
			goto error;
		}
	}

	*node = child;

	return init_data;

error:
	of_node_put(child);

	return NULL;
}

/**
 * of_get_child_regulator - get a child regulator device node
 * based on supply name
 * @parent: Parent device node
 * @prop_name: Combination regulator supply name and "-supply"
 *
 * Traverse all child nodes.
 * Extract the child regulator device node corresponding to the supply name.
 *
 * Return: Pointer to the &struct device_node corresponding to the regulator
 *	   if found, or %NULL if not found.
 */
static struct device_node *of_get_child_regulator(struct device_node *parent,
						  const char *prop_name)
{
	struct device_node *regnode = NULL;
	struct device_node *child = NULL;

	for_each_child_of_node(parent, child) {
		regnode = of_parse_phandle(child, prop_name, 0);
		if (regnode)
			goto err_node_put;

		regnode = of_get_child_regulator(child, prop_name);
		if (regnode)
			goto err_node_put;
	}
	return NULL;

err_node_put:
	of_node_put(child);
	return regnode;
}

/**
 * of_get_regulator - get a regulator device node based on supply name
 * @dev: Device pointer for the consumer (of regulator) device
 * @supply: regulator supply name
 *
 * Extract the regulator device node corresponding to the supply name.
 *
 * Return: Pointer to the &struct device_node corresponding to the regulator
 *	   if found, or %NULL if not found.
 */
static struct device_node *of_get_regulator(struct device *dev, const char *supply)
{
	struct device_node *regnode = NULL;
	char prop_name[64]; /* 64 is max size of property name */

	dev_dbg(dev, "Looking up %s-supply from device tree\n", supply);

	snprintf(prop_name, 64, "%s-supply", supply);
	regnode = of_parse_phandle(dev->of_node, prop_name, 0);
	if (regnode)
		return regnode;

	regnode = of_get_child_regulator(dev->of_node, prop_name);
	if (regnode)
		return regnode;

	dev_dbg(dev, "Looking up %s property in node %pOF failed\n", prop_name, dev->of_node);
	return NULL;
}

static struct regulator_dev *of_find_regulator_by_node(struct device_node *np)
{
	struct device *dev;

	dev = class_find_device_by_of_node(&regulator_class, np);

	return dev ? dev_to_rdev(dev) : NULL;
}

/**
 * of_regulator_dev_lookup - lookup a regulator device with device tree only
 * @dev: Device pointer for regulator supply lookup.
 * @supply: Supply name or regulator ID.
 *
 * Return: Pointer to the &struct regulator_dev on success, or ERR_PTR()
 *	   encoded value on error.
 *
 * If successful, returns a pointer to the &struct regulator_dev that
 * corresponds to the name @supply and with the embedded &struct device
 * refcount incremented by one. The refcount must be dropped by calling
 * put_device().
 *
 * On failure one of the following ERR_PTR() encoded values is returned:
 * * -%ENODEV if lookup fails permanently.
 * * -%EPROBE_DEFER if lookup could succeed in the future.
 */
struct regulator_dev *of_regulator_dev_lookup(struct device *dev,
					      const char *supply)
{
	struct regulator_dev *r;
	struct device_node *node;

	node = of_get_regulator(dev, supply);
	if (node) {
		r = of_find_regulator_by_node(node);
		of_node_put(node);
		if (r)
			return r;

		/*
		 * We have a node, but there is no device.
		 * assume it has not registered yet.
		 */
		return ERR_PTR(-EPROBE_DEFER);
	}

	return ERR_PTR(-ENODEV);
}

/*
 * Returns number of regulators coupled with rdev.
 */
int of_get_n_coupled(struct regulator_dev *rdev)
{
	struct device_node *node = rdev->dev.of_node;
	int n_phandles;

	n_phandles = of_count_phandle_with_args(node,
						"regulator-coupled-with",
						NULL);

	return (n_phandles > 0) ? n_phandles : 0;
}

/* Looks for "to_find" device_node in src's "regulator-coupled-with" property */
static bool of_coupling_find_node(struct device_node *src,
				  struct device_node *to_find,
				  int *index)
{
	int n_phandles, i;
	bool found = false;

	n_phandles = of_count_phandle_with_args(src,
						"regulator-coupled-with",
						NULL);

	for (i = 0; i < n_phandles; i++) {
		struct device_node *tmp = of_parse_phandle(src,
					   "regulator-coupled-with", i);

		if (!tmp)
			break;

		/* found */
		if (tmp == to_find)
			found = true;

		of_node_put(tmp);

		if (found) {
			*index = i;
			break;
		}
	}

	return found;
}

/**
 * of_check_coupling_data - Parse rdev's coupling properties and check data
 *			    consistency
 * @rdev: pointer to regulator_dev whose data is checked
 *
 * Function checks if all the following conditions are met:
 * - rdev's max_spread is greater than 0
 * - all coupled regulators have the same max_spread
 * - all coupled regulators have the same number of regulator_dev phandles
 * - all regulators are linked to each other
 *
 * Return: True if all conditions are met; false otherwise.
 */
bool of_check_coupling_data(struct regulator_dev *rdev)
{
	struct device_node *node = rdev->dev.of_node;
	int n_phandles = of_get_n_coupled(rdev);
	struct device_node *c_node;
	int index;
	int i;
	bool ret = true;

	/* iterate over rdev's phandles */
	for (i = 0; i < n_phandles; i++) {
		int max_spread = rdev->constraints->max_spread[i];
		int c_max_spread, c_n_phandles;

		if (max_spread <= 0) {
			dev_err(&rdev->dev, "max_spread value invalid\n");
			return false;
		}

		c_node = of_parse_phandle(node,
					  "regulator-coupled-with", i);

		if (!c_node)
			ret = false;

		c_n_phandles = of_count_phandle_with_args(c_node,
							  "regulator-coupled-with",
							  NULL);

		if (c_n_phandles != n_phandles) {
			dev_err(&rdev->dev, "number of coupled reg phandles mismatch\n");
			ret = false;
			goto clean;
		}

		if (!of_coupling_find_node(c_node, node, &index)) {
			dev_err(&rdev->dev, "missing 2-way linking for coupled regulators\n");
			ret = false;
			goto clean;
		}

		if (of_property_read_u32_index(c_node, "regulator-coupled-max-spread",
					       index, &c_max_spread)) {
			ret = false;
			goto clean;
		}

		if (c_max_spread != max_spread) {
			dev_err(&rdev->dev,
				"coupled regulators max_spread mismatch\n");
			ret = false;
			goto clean;
		}

clean:
		of_node_put(c_node);
		if (!ret)
			break;
	}

	return ret;
}

/**
 * of_parse_coupled_regulator() - Get regulator_dev pointer from rdev's property
 * @rdev: Pointer to regulator_dev, whose DTS is used as a source to parse
 *	  "regulator-coupled-with" property
 * @index: Index in phandles array
 *
 * Return: Pointer to the &struct regulator_dev parsed from DTS, or %NULL if
 *	   it has not yet been registered.
 */
struct regulator_dev *of_parse_coupled_regulator(struct regulator_dev *rdev,
						 int index)
{
	struct device_node *node = rdev->dev.of_node;
	struct device_node *c_node;
	struct regulator_dev *c_rdev;

	c_node = of_parse_phandle(node, "regulator-coupled-with", index);
	if (!c_node)
		return NULL;

	c_rdev = of_find_regulator_by_node(c_node);

	of_node_put(c_node);

	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.
 *
 * 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, and @consumers will not be
 * changed.
 *
 * Return: Number of regulators on success, or a negative error number
 *	   on failure.
 */
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 regulator_bulk_data *_consumers = NULL;
	struct property *prop;
	int i, n = 0, ret;
	char name[64];

	/*
	 * 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 (IS_ERR(tmp)) {
				ret = PTR_ERR(tmp);
				goto error;
			}
			_consumers[n].consumer = tmp;
			n++;
			continue;
		}
	}
	if (_consumers) {
		*consumers = _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);
	kfree(_consumers);
	return ret;
}
EXPORT_SYMBOL_GPL(of_regulator_bulk_get_all);
