diff options
Diffstat (limited to 'drivers/gpio/devres.c')
| -rw-r--r-- | drivers/gpio/devres.c | 85 | 
1 files changed, 85 insertions, 0 deletions
diff --git a/drivers/gpio/devres.c b/drivers/gpio/devres.c index 3e7812f0405e..307464fd015f 100644 --- a/drivers/gpio/devres.c +++ b/drivers/gpio/devres.c @@ -15,10 +15,95 @@   */  #include <linux/module.h> +#include <linux/err.h>  #include <linux/gpio.h> +#include <linux/gpio/consumer.h>  #include <linux/device.h>  #include <linux/gfp.h> +static void devm_gpiod_release(struct device *dev, void *res) +{ +	struct gpio_desc **desc = res; + +	gpiod_put(*desc); +} + +static int devm_gpiod_match(struct device *dev, void *res, void *data) +{ +	struct gpio_desc **this = res, **gpio = data; + +	return *this == *gpio; +} + +/** + * devm_gpiod_get - Resource-managed gpiod_get() + * @dev:	GPIO consumer + * @con_id:	function within the GPIO consumer + * + * Managed gpiod_get(). GPIO descriptors returned from this function are + * automatically disposed on driver detach. See gpiod_get() for detailed + * information about behavior and return values. + */ +struct gpio_desc *__must_check devm_gpiod_get(struct device *dev, +					      const char *con_id) +{ +	return devm_gpiod_get_index(dev, con_id, 0); +} +EXPORT_SYMBOL(devm_gpiod_get); + +/** + * devm_gpiod_get_index - Resource-managed gpiod_get_index() + * @dev:	GPIO consumer + * @con_id:	function within the GPIO consumer + * @idx:	index of the GPIO to obtain in the consumer + * + * Managed gpiod_get_index(). GPIO descriptors returned from this function are + * automatically disposed on driver detach. See gpiod_get_index() for detailed + * information about behavior and return values. + */ +struct gpio_desc *__must_check devm_gpiod_get_index(struct device *dev, +						    const char *con_id, +						    unsigned int idx) +{ +	struct gpio_desc **dr; +	struct gpio_desc *desc; + +	dr = devres_alloc(devm_gpiod_release, sizeof(struct gpiod_desc *), +			  GFP_KERNEL); +	if (!dr) +		return ERR_PTR(-ENOMEM); + +	desc = gpiod_get_index(dev, con_id, idx); +	if (IS_ERR(desc)) { +		devres_free(dr); +		return desc; +	} + +	*dr = desc; +	devres_add(dev, dr); + +	return desc; +} +EXPORT_SYMBOL(devm_gpiod_get_index); + +/** + * devm_gpiod_put - Resource-managed gpiod_put() + * @desc:	GPIO descriptor to dispose of + * + * Dispose of a GPIO descriptor obtained with devm_gpiod_get() or + * devm_gpiod_get_index(). Normally this function will not be called as the GPIO + * will be disposed of by the resource management code. + */ +void devm_gpiod_put(struct device *dev, struct gpio_desc *desc) +{ +	WARN_ON(devres_release(dev, devm_gpiod_release, devm_gpiod_match, +		&desc)); +} +EXPORT_SYMBOL(devm_gpiod_put); + + + +  static void devm_gpio_release(struct device *dev, void *res)  {  	unsigned *gpio = res;  | 
