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

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
...@@ -284,3 +284,7 @@ CLOCK ...@@ -284,3 +284,7 @@ CLOCK
PINCTRL PINCTRL
devm_pinctrl_get() devm_pinctrl_get()
devm_pinctrl_put() devm_pinctrl_put()
PWM
devm_pwm_get()
devm_pwm_put()
...@@ -36,7 +36,8 @@ Legacy users can request a PWM device using pwm_request() and free it ...@@ -36,7 +36,8 @@ Legacy users can request a PWM device using pwm_request() and free it
after usage with pwm_free(). after usage with pwm_free().
New users should use the pwm_get() function and pass to it the consumer 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: After being requested a PWM has to be configured using:
......
...@@ -646,6 +646,64 @@ void pwm_put(struct pwm_device *pwm) ...@@ -646,6 +646,64 @@ void pwm_put(struct pwm_device *pwm)
} }
EXPORT_SYMBOL_GPL(pwm_put); 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 #ifdef CONFIG_DEBUG_FS
static void pwm_dbg_show(struct pwm_chip *chip, struct seq_file *s) static void pwm_dbg_show(struct pwm_chip *chip, struct seq_file *s)
{ {
......
...@@ -148,6 +148,9 @@ struct pwm_device *pwm_request_from_chip(struct pwm_chip *chip, ...@@ -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); struct pwm_device *pwm_get(struct device *dev, const char *consumer);
void pwm_put(struct pwm_device *pwm); 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 pwm_lookup {
struct list_head list; struct list_head list;
const char *provider; const char *provider;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment