From 29a1f2333e07bbbecb920cc78fd035fe8f53207a Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Fri, 25 Apr 2014 17:10:06 +0200 Subject: gpio: Add helpers for optional GPIOs Introduce gpiod_get_optional() and gpiod_get_index_optional() helpers that make it easier for drivers to handle optional GPIOs. Currently in order to handle optional GPIOs, a driver needs to special case error handling for -ENOENT, such as this: gpio = gpiod_get(dev, "foo"); if (IS_ERR(gpio)) { if (PTR_ERR(gpio) != -ENOENT) return PTR_ERR(gpio); gpio = NULL; } if (gpio) { /* set up GPIO */ } With these new helpers the above is reduced to: gpio = gpiod_get_optional(dev, "foo"); if (IS_ERR(gpio)) return PTR_ERR(gpio); if (gpio) { /* set up GPIO */ } While at it, device-managed variants of these functions are also provided. Signed-off-by: Thierry Reding Reviewed-by: Alexandre Courbot Signed-off-by: Linus Walleij --- drivers/gpio/devres.c | 43 +++++++++++++++++++++++++++++++++++++++++++ drivers/gpio/gpiolib.c | 43 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 86 insertions(+) (limited to 'drivers/gpio') diff --git a/drivers/gpio/devres.c b/drivers/gpio/devres.c index 307464fd015..65978cf85f7 100644 --- a/drivers/gpio/devres.c +++ b/drivers/gpio/devres.c @@ -51,6 +51,22 @@ struct gpio_desc *__must_check devm_gpiod_get(struct device *dev, } EXPORT_SYMBOL(devm_gpiod_get); +/** + * devm_gpiod_get_optional - Resource-managed gpiod_get_optional() + * @dev: GPIO consumer + * @con_id: function within the GPIO consumer + * + * Managed gpiod_get_optional(). GPIO descriptors returned from this function + * are automatically disposed on driver detach. See gpiod_get_optional() for + * detailed information about behavior and return values. + */ +struct gpio_desc *__must_check devm_gpiod_get_optional(struct device *dev, + const char *con_id) +{ + return devm_gpiod_get_index_optional(dev, con_id, 0); +} +EXPORT_SYMBOL(devm_gpiod_get_optional); + /** * devm_gpiod_get_index - Resource-managed gpiod_get_index() * @dev: GPIO consumer @@ -86,6 +102,33 @@ struct gpio_desc *__must_check devm_gpiod_get_index(struct device *dev, } EXPORT_SYMBOL(devm_gpiod_get_index); +/** + * devm_gpiod_get_index_optional - Resource-managed gpiod_get_index_optional() + * @dev: GPIO consumer + * @con_id: function within the GPIO consumer + * @index: index of the GPIO to obtain in the consumer + * + * Managed gpiod_get_index_optional(). GPIO descriptors returned from this + * function are automatically disposed on driver detach. See + * gpiod_get_index_optional() for detailed information about behavior and + * return values. + */ +struct gpio_desc *__must_check devm_gpiod_get_index_optional(struct device *dev, + const char *con_id, + unsigned int index) +{ + struct gpio_desc *desc; + + desc = devm_gpiod_get_index(dev, con_id, index); + if (IS_ERR(desc)) { + if (PTR_ERR(desc) == -ENOENT) + return NULL; + } + + return desc; +} +EXPORT_SYMBOL(devm_gpiod_get_index_optional); + /** * devm_gpiod_put - Resource-managed gpiod_put() * @desc: GPIO descriptor to dispose of diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index 4ad110e793c..d9c9cb4665d 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c @@ -2737,6 +2737,22 @@ struct gpio_desc *__must_check gpiod_get(struct device *dev, const char *con_id) } EXPORT_SYMBOL_GPL(gpiod_get); +/** + * gpiod_get_optional - obtain an optional GPIO for a given GPIO function + * @dev: GPIO consumer, can be NULL for system-global GPIOs + * @con_id: function within the GPIO consumer + * + * This is equivalent to gpiod_get(), except that when no GPIO was assigned to + * the requested function it will return NULL. This is convenient for drivers + * that need to handle optional GPIOs. + */ +struct gpio_desc *__must_check gpiod_get_optional(struct device *dev, + const char *con_id) +{ + return gpiod_get_index_optional(dev, con_id, 0); +} +EXPORT_SYMBOL_GPL(gpiod_get_optional); + /** * gpiod_get_index - obtain a GPIO from a multi-index GPIO function * @dev: GPIO consumer, can be NULL for system-global GPIOs @@ -2799,6 +2815,33 @@ struct gpio_desc *__must_check gpiod_get_index(struct device *dev, } EXPORT_SYMBOL_GPL(gpiod_get_index); +/** + * gpiod_get_index_optional - obtain an optional GPIO from a multi-index GPIO + * function + * @dev: GPIO consumer, can be NULL for system-global GPIOs + * @con_id: function within the GPIO consumer + * @index: index of the GPIO to obtain in the consumer + * + * This is equivalent to gpiod_get_index(), except that when no GPIO with the + * specified index was assigned to the requested function it will return NULL. + * This is convenient for drivers that need to handle optional GPIOs. + */ +struct gpio_desc *__must_check gpiod_get_index_optional(struct device *dev, + const char *con_id, + unsigned int index) +{ + struct gpio_desc *desc; + + desc = gpiod_get_index(dev, con_id, index); + if (IS_ERR(desc)) { + if (PTR_ERR(desc) == -ENOENT) + return NULL; + } + + return desc; +} +EXPORT_SYMBOL_GPL(gpiod_get_index_optional); + /** * gpiod_put - dispose of a GPIO descriptor * @desc: GPIO descriptor to dispose of -- cgit v1.2.3-70-g09d2