Unverified Commit fd184506 authored by Zev Weiss's avatar Zev Weiss Committed by Mark Brown
Browse files

regulator: devres: Add devm_regulator_bulk_get_exclusive()



We had an exclusive variant of the devm_regulator_get() API, but no
corresponding variant for the bulk API; let's add one now.  We add a
generalized version of the existing regulator_bulk_get() function that
additionally takes a get_type parameter and redefine
regulator_bulk_get() in terms of it, then do similarly with
devm_regulator_bulk_get(), and finally add the new
devm_regulator_bulk_get_exclusive().

Signed-off-by: default avatarZev Weiss <zev@bewilderbeest.net>
Link: https://lore.kernel.org/r/20221031233704.22575-2-zev@bewilderbeest.net


Signed-off-by: default avatarMark Brown <broonie@kernel.org>
parent 9abf2313
Loading
Loading
Loading
Loading
+24 −18
Original line number Diff line number Diff line
@@ -4778,22 +4778,8 @@ static int _notifier_call_chain(struct regulator_dev *rdev,
	return blocking_notifier_call_chain(&rdev->notifier, event, data);
}

/**
 * regulator_bulk_get - get multiple regulator consumers
 *
 * @dev:           Device to supply
 * @num_consumers: Number of consumers to register
 * @consumers:     Configuration of consumers; clients are stored here.
 *
 * @return 0 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 regulator_bulk_get(struct device *dev, int num_consumers,
		       struct regulator_bulk_data *consumers)
int _regulator_bulk_get(struct device *dev, int num_consumers,
			struct regulator_bulk_data *consumers, enum regulator_get_type get_type)
{
	int i;
	int ret;
@@ -4802,8 +4788,8 @@ int regulator_bulk_get(struct device *dev, int num_consumers,
		consumers[i].consumer = NULL;

	for (i = 0; i < num_consumers; i++) {
		consumers[i].consumer = regulator_get(dev,
						      consumers[i].supply);
		consumers[i].consumer = _regulator_get(dev,
						       consumers[i].supply, get_type);
		if (IS_ERR(consumers[i].consumer)) {
			ret = dev_err_probe(dev, PTR_ERR(consumers[i].consumer),
					    "Failed to get supply '%s'",
@@ -4830,6 +4816,26 @@ int regulator_bulk_get(struct device *dev, int num_consumers,

	return ret;
}

/**
 * regulator_bulk_get - get multiple regulator consumers
 *
 * @dev:           Device to supply
 * @num_consumers: Number of consumers to register
 * @consumers:     Configuration of consumers; clients are stored here.
 *
 * @return 0 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 regulator_bulk_get(struct device *dev, int num_consumers,
		       struct regulator_bulk_data *consumers)
{
	return _regulator_bulk_get(dev, num_consumers, consumers, NORMAL_GET);
}
EXPORT_SYMBOL_GPL(regulator_bulk_get);

static void regulator_bulk_enable_async(void *data, async_cookie_t cookie)
+48 −18
Original line number Diff line number Diff line
@@ -186,6 +186,30 @@ static void devm_regulator_bulk_release(struct device *dev, void *res)
	regulator_bulk_free(devres->num_consumers, devres->consumers);
}

static int _devm_regulator_bulk_get(struct device *dev, int num_consumers,
				    struct regulator_bulk_data *consumers,
				    enum regulator_get_type get_type)
{
	struct regulator_bulk_devres *devres;
	int ret;

	devres = devres_alloc(devm_regulator_bulk_release,
			      sizeof(*devres), GFP_KERNEL);
	if (!devres)
		return -ENOMEM;

	ret = _regulator_bulk_get(dev, num_consumers, consumers, get_type);
	if (!ret) {
		devres->consumers = consumers;
		devres->num_consumers = num_consumers;
		devres_add(dev, devres);
	} else {
		devres_free(devres);
	}

	return ret;
}

/**
 * devm_regulator_bulk_get - managed get multiple regulator consumers
 *
@@ -204,26 +228,32 @@ static void devm_regulator_bulk_release(struct device *dev, void *res)
int devm_regulator_bulk_get(struct device *dev, int num_consumers,
			    struct regulator_bulk_data *consumers)
{
	struct regulator_bulk_devres *devres;
	int ret;

	devres = devres_alloc(devm_regulator_bulk_release,
			      sizeof(*devres), GFP_KERNEL);
	if (!devres)
		return -ENOMEM;

	ret = regulator_bulk_get(dev, num_consumers, consumers);
	if (!ret) {
		devres->consumers = consumers;
		devres->num_consumers = num_consumers;
		devres_add(dev, devres);
	} else {
		devres_free(devres);
	return _devm_regulator_bulk_get(dev, num_consumers, consumers, NORMAL_GET);
}
EXPORT_SYMBOL_GPL(devm_regulator_bulk_get);

	return ret;
/**
 * devm_regulator_bulk_get_exclusive - managed exclusive get of multiple
 * regulator consumers
 *
 * @dev:           device to supply
 * @num_consumers: number of consumers to register
 * @consumers:     configuration of consumers; clients are stored here.
 *
 * @return 0 on success, an errno on failure.
 *
 * This helper function allows drivers to exclusively get several
 * regulator consumers in one operation with management, the regulators
 * will automatically be freed when the device is unbound.  If any of
 * the regulators cannot be acquired then any regulators that were
 * allocated will be freed before returning to the caller.
 */
int devm_regulator_bulk_get_exclusive(struct device *dev, int num_consumers,
				      struct regulator_bulk_data *consumers)
{
	return _devm_regulator_bulk_get(dev, num_consumers, consumers, EXCLUSIVE_GET);
}
EXPORT_SYMBOL_GPL(devm_regulator_bulk_get);
EXPORT_SYMBOL_GPL(devm_regulator_bulk_get_exclusive);

/**
 * devm_regulator_bulk_get_const - devm_regulator_bulk_get() w/ const data
+2 −0
Original line number Diff line number Diff line
@@ -122,4 +122,6 @@ enum regulator_get_type {

struct regulator *_regulator_get(struct device *dev, const char *id,
				 enum regulator_get_type get_type);
int _regulator_bulk_get(struct device *dev, int num_consumers,
			struct regulator_bulk_data *consumers, enum regulator_get_type get_type);
#endif
+2 −0
Original line number Diff line number Diff line
@@ -247,6 +247,8 @@ int __must_check 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);
void devm_regulator_bulk_put(struct regulator_bulk_data *consumers);
int __must_check devm_regulator_bulk_get_exclusive(struct device *dev, int num_consumers,
						   struct regulator_bulk_data *consumers);
int __must_check devm_regulator_bulk_get_const(
	struct device *dev, int num_consumers,
	const struct regulator_bulk_data *in_consumers,