Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 6354316d authored by Alexandre Courbot's avatar Alexandre Courbot Committed by Thierry Reding
Browse files

pwm: add devm_pwm_get() and devm_pwm_put()



Add resource managed variants of pwm_get() and pwm_put() for
convenience. Code is largely inspired by the equivalent devm functions
of the regulator framework.

Signed-off-by: default avatarAlexandre Courbot <acourbot@nvidia.com>
Signed-off-by: default avatarThierry Reding <thierry.reding@avionic-design.de>
parent 0aa0869c
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -284,3 +284,7 @@ CLOCK
PINCTRL
  devm_pinctrl_get()
  devm_pinctrl_put()

PWM
  devm_pwm_get()
  devm_pwm_put()
+2 −1
Original line number Diff line number Diff line
@@ -36,7 +36,8 @@ Legacy users can request a PWM device using pwm_request() and free it
after usage with pwm_free().

New users should use the pwm_get() function and pass to it the consumer
device or a consumer name. pwm_put() is used to free the PWM device.
device or a consumer name. pwm_put() is used to free the PWM device. Managed
variants of these functions, devm_pwm_get() and devm_pwm_put(), also exist.

After being requested a PWM has to be configured using:

+58 −0
Original line number Diff line number Diff line
@@ -646,6 +646,64 @@ void pwm_put(struct pwm_device *pwm)
}
EXPORT_SYMBOL_GPL(pwm_put);

static void devm_pwm_release(struct device *dev, void *res)
{
	pwm_put(*(struct pwm_device **)res);
}

/**
 * devm_pwm_get() - resource managed pwm_get()
 * @dev: device for PWM consumer
 * @con_id: consumer name
 *
 * This function performs like pwm_get() but the acquired PWM device will
 * automatically be released on driver detach.
 */
struct pwm_device *devm_pwm_get(struct device *dev, const char *con_id)
{
	struct pwm_device **ptr, *pwm;

	ptr = devres_alloc(devm_pwm_release, sizeof(**ptr), GFP_KERNEL);
	if (!ptr)
		return ERR_PTR(-ENOMEM);

	pwm = pwm_get(dev, con_id);
	if (!IS_ERR(pwm)) {
		*ptr = pwm;
		devres_add(dev, ptr);
	} else {
		devres_free(ptr);
	}

	return pwm;
}
EXPORT_SYMBOL_GPL(devm_pwm_get);

static int devm_pwm_match(struct device *dev, void *res, void *data)
{
	struct pwm_device **p = res;

	if (WARN_ON(!p || !*p))
		return 0;

	return *p == data;
}

/**
 * devm_pwm_put() - resource managed pwm_put()
 * @dev: device for PWM consumer
 * @pwm: PWM device
 *
 * Release a PWM previously allocated using devm_pwm_get(). Calling this
 * function is usually not needed because devm-allocated resources are
 * automatically released on driver detach.
 */
void devm_pwm_put(struct device *dev, struct pwm_device *pwm)
{
	WARN_ON(devres_release(dev, devm_pwm_release, devm_pwm_match, pwm));
}
EXPORT_SYMBOL_GPL(devm_pwm_put);

#ifdef CONFIG_DEBUG_FS
static void pwm_dbg_show(struct pwm_chip *chip, struct seq_file *s)
{
+3 −0
Original line number Diff line number Diff line
@@ -148,6 +148,9 @@ struct pwm_device *pwm_request_from_chip(struct pwm_chip *chip,
struct pwm_device *pwm_get(struct device *dev, const char *consumer);
void pwm_put(struct pwm_device *pwm);

struct pwm_device *devm_pwm_get(struct device *dev, const char *consumer);
void devm_pwm_put(struct device *dev, struct pwm_device *pwm);

struct pwm_lookup {
	struct list_head list;
	const char *provider;