From: Hauke Mehrtens Date: Sat, 31 May 2014 15:18:28 +0000 (+0200) Subject: backports: add devm_gpio_request{_one}() X-Git-Url: http://git.lede-project.org./?a=commitdiff_plain;h=5104d1ee9538a86e30df5fcdcda72a353b66d5ae;p=openwrt%2Fstaging%2Fblogic.git backports: add devm_gpio_request{_one}() These two functions are used by some drivers, but not available in all kernel versions. Signed-off-by: Hauke Mehrtens --- diff --git a/backport/backport-include/linux/gpio.h b/backport/backport-include/linux/gpio.h new file mode 100644 index 000000000000..8fb7211d9f13 --- /dev/null +++ b/backport/backport-include/linux/gpio.h @@ -0,0 +1,29 @@ +#ifndef __BACKPORT_LINUX_GPIO_H +#define __BACKPORT_LINUX_GPIO_H +#include_next + +#if LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0) +#define devm_gpio_request_one LINUX_BACKPORT(devm_gpio_request_one) +#define devm_gpio_request LINUX_BACKPORT(devm_gpio_request) +#ifdef CONFIG_GPIOLIB +int devm_gpio_request(struct device *dev, unsigned gpio, const char *label); +int devm_gpio_request_one(struct device *dev, unsigned gpio, + unsigned long flags, const char *label); +#else +static inline int devm_gpio_request(struct device *dev, unsigned gpio, + const char *label) +{ + WARN_ON(1); + return -EINVAL; +} + +static inline int devm_gpio_request_one(struct device *dev, unsigned gpio, + unsigned long flags, const char *label) +{ + WARN_ON(1); + return -EINVAL; +} +#endif /* CONFIG_GPIOLIB */ +#endif + +#endif /* __BACKPORT_LINUX_GPIO_H */ diff --git a/backport/compat/compat-3.5.c b/backport/compat/compat-3.5.c index 2727eb323b9c..13f64768ccae 100644 --- a/backport/compat/compat-3.5.c +++ b/backport/compat/compat-3.5.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,2,0)) @@ -73,3 +74,79 @@ int ptp_clock_index(struct ptp_clock *ptp) } EXPORT_SYMBOL(ptp_clock_index); #endif /* CONFIG_PTP_1588_CLOCK */ + +#ifdef CONFIG_GPIOLIB +static void devm_gpio_release(struct device *dev, void *res) +{ + unsigned *gpio = res; + + gpio_free(*gpio); +} + +/** + * devm_gpio_request - request a GPIO for a managed device + * @dev: device to request the GPIO for + * @gpio: GPIO to allocate + * @label: the name of the requested GPIO + * + * Except for the extra @dev argument, this function takes the + * same arguments and performs the same function as + * gpio_request(). GPIOs requested with this function will be + * automatically freed on driver detach. + * + * If an GPIO allocated with this function needs to be freed + * separately, devm_gpio_free() must be used. + */ + +int devm_gpio_request(struct device *dev, unsigned gpio, const char *label) +{ + unsigned *dr; + int rc; + + dr = devres_alloc(devm_gpio_release, sizeof(unsigned), GFP_KERNEL); + if (!dr) + return -ENOMEM; + + rc = gpio_request(gpio, label); + if (rc) { + devres_free(dr); + return rc; + } + + *dr = gpio; + devres_add(dev, dr); + + return 0; +} +EXPORT_SYMBOL_GPL(devm_gpio_request); + +/** + * devm_gpio_request_one - request a single GPIO with initial setup + * @dev: device to request for + * @gpio: the GPIO number + * @flags: GPIO configuration as specified by GPIOF_* + * @label: a literal description string of this GPIO + */ +int devm_gpio_request_one(struct device *dev, unsigned gpio, + unsigned long flags, const char *label) +{ + unsigned *dr; + int rc; + + dr = devres_alloc(devm_gpio_release, sizeof(unsigned), GFP_KERNEL); + if (!dr) + return -ENOMEM; + + rc = gpio_request_one(gpio, flags, label); + if (rc) { + devres_free(dr); + return rc; + } + + *dr = gpio; + devres_add(dev, dr); + + return 0; +} +EXPORT_SYMBOL_GPL(devm_gpio_request_one); +#endif /* CONFIG_GPIOLIB */