Message ID | 20200827062804.16730-1-krzk@kernel.org (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | [v3,1/2] gpio: Add devm_fwnode_gpiod_get_optional() helpers | expand |
On Thu, Aug 27, 2020 at 9:28 AM Krzysztof Kozlowski <krzk@kernel.org> wrote: > > Add devm_fwnode_gpiod_get_optional() and > devm_fwnode_gpiod_get_index_optional() helpers, similar to regular > devm_gpiod optional versions. Drivers getting GPIOs from a firmware > node might use it to remove some boilerplate code. > For both: Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com> > Signed-off-by: Krzysztof Kozlowski <krzk@kernel.org> > > --- > > Changes since v2: > 1. Return NULL > > Changes since v1: > 1. New patch > --- > drivers/gpio/gpiolib-devres.c | 71 +++++++++++++++++++++++++++++++++++ > include/linux/gpio/consumer.h | 30 +++++++++++++++ > 2 files changed, 101 insertions(+) > > diff --git a/drivers/gpio/gpiolib-devres.c b/drivers/gpio/gpiolib-devres.c > index 7dbce4c4ebdf..f8476f6a65cc 100644 > --- a/drivers/gpio/gpiolib-devres.c > +++ b/drivers/gpio/gpiolib-devres.c > @@ -184,6 +184,37 @@ struct gpio_desc *devm_gpiod_get_from_of_node(struct device *dev, > } > EXPORT_SYMBOL_GPL(devm_gpiod_get_from_of_node); > > +/** > + * devm_fwnode_gpiod_get_optional - Resource-managed fwnode_gpiod_get_index() > + * for optional GPIO > + * @dev: GPIO consumer > + * @fwnode: firmware node containing GPIO reference > + * @con_id: function within the GPIO consumer > + * @flags: GPIO initialization flags > + * @label: label to attach to the requested GPIO > + * > + * GPIO descriptors returned from this function are automatically disposed on > + * driver detach. > + * > + * This is equivalent to devm_fwnode_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. > + * > + * On successful request the GPIO pin is configured in accordance with > + * provided @flags. > + */ > +struct gpio_desc *devm_fwnode_gpiod_get_optional(struct device *dev, > + struct fwnode_handle *fwnode, > + const char *con_id, > + enum gpiod_flags flags, > + const char *label) > +{ > + return devm_fwnode_gpiod_get_index_optional(dev, fwnode, con_id, 0, > + flags, label); > +} > +EXPORT_SYMBOL_GPL(devm_fwnode_gpiod_get_optional); > + > /** > * devm_fwnode_gpiod_get_index - get a GPIO descriptor from a given node > * @dev: GPIO consumer > @@ -226,6 +257,46 @@ struct gpio_desc *devm_fwnode_gpiod_get_index(struct device *dev, > } > EXPORT_SYMBOL_GPL(devm_fwnode_gpiod_get_index); > > +/** > + * devm_fwnode_gpiod_get_index_optional - Resource-managed fwnode_gpiod_get_index() > + * for optional GPIO > + * @dev: GPIO consumer > + * @fwnode: firmware node containing GPIO reference > + * @con_id: function within the GPIO consumer > + * @index: index of the GPIO to obtain in the consumer > + * @flags: GPIO initialization flags > + * @label: label to attach to the requested GPIO > + * > + * GPIO descriptors returned from this function are automatically disposed on > + * driver detach. > + * > + * This is equivalent to devm_fwnode_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. > + * > + * On successful request the GPIO pin is configured in accordance with > + * provided @flags. > + */ > +struct gpio_desc *devm_fwnode_gpiod_get_index_optional(struct device *dev, > + struct fwnode_handle *fwnode, > + const char *con_id, int index, > + enum gpiod_flags flags, > + const char *label) > +{ > + struct gpio_desc *desc; > + > + desc = devm_fwnode_gpiod_get_index(dev, fwnode, con_id, index, flags, > + label); > + if (IS_ERR(desc)) { > + if (PTR_ERR(desc) == -ENOENT) > + return NULL; > + } > + > + return desc; > +} > +EXPORT_SYMBOL_GPL(devm_fwnode_gpiod_get_index_optional); > + > /** > * devm_gpiod_get_index_optional - Resource-managed gpiod_get_index_optional() > * @dev: GPIO consumer > diff --git a/include/linux/gpio/consumer.h b/include/linux/gpio/consumer.h > index 901aab89d025..7854d80b1e9a 100644 > --- a/include/linux/gpio/consumer.h > +++ b/include/linux/gpio/consumer.h > @@ -183,11 +183,21 @@ struct gpio_desc *fwnode_gpiod_get_index(struct fwnode_handle *fwnode, > const char *con_id, int index, > enum gpiod_flags flags, > const char *label); > +struct gpio_desc *devm_fwnode_gpiod_get_optional(struct device *dev, > + struct fwnode_handle *fwnode, > + const char *con_id, > + enum gpiod_flags flags, > + const char *label); > struct gpio_desc *devm_fwnode_gpiod_get_index(struct device *dev, > struct fwnode_handle *child, > const char *con_id, int index, > enum gpiod_flags flags, > const char *label); > +struct gpio_desc *devm_fwnode_gpiod_get_index_optional(struct device *dev, > + struct fwnode_handle *fwnode, > + const char *con_id, int index, > + enum gpiod_flags flags, > + const char *label); > > #else /* CONFIG_GPIOLIB */ > > @@ -562,6 +572,16 @@ struct gpio_desc *fwnode_gpiod_get_index(struct fwnode_handle *fwnode, > return ERR_PTR(-ENOSYS); > } > > +static inline > +struct gpio_desc *devm_fwnode_gpiod_get_optional(struct device *dev, > + struct fwnode_handle *fwnode, > + const char *con_id, > + enum gpiod_flags flags, > + const char *label) > +{ > + return NULL; > +} > + > static inline > struct gpio_desc *devm_fwnode_gpiod_get_index(struct device *dev, > struct fwnode_handle *fwnode, > @@ -572,6 +592,16 @@ struct gpio_desc *devm_fwnode_gpiod_get_index(struct device *dev, > return ERR_PTR(-ENOSYS); > } > > +static inline > +struct gpio_desc *devm_fwnode_gpiod_get_index_optional(struct device *dev, > + struct fwnode_handle *fwnode, > + const char *con_id, int index, > + enum gpiod_flags flags, > + const char *label) > +{ > + return NULL; > +} > + > #endif /* CONFIG_GPIOLIB */ > > static inline > -- > 2.17.1 >
diff --git a/drivers/gpio/gpiolib-devres.c b/drivers/gpio/gpiolib-devres.c index 7dbce4c4ebdf..f8476f6a65cc 100644 --- a/drivers/gpio/gpiolib-devres.c +++ b/drivers/gpio/gpiolib-devres.c @@ -184,6 +184,37 @@ struct gpio_desc *devm_gpiod_get_from_of_node(struct device *dev, } EXPORT_SYMBOL_GPL(devm_gpiod_get_from_of_node); +/** + * devm_fwnode_gpiod_get_optional - Resource-managed fwnode_gpiod_get_index() + * for optional GPIO + * @dev: GPIO consumer + * @fwnode: firmware node containing GPIO reference + * @con_id: function within the GPIO consumer + * @flags: GPIO initialization flags + * @label: label to attach to the requested GPIO + * + * GPIO descriptors returned from this function are automatically disposed on + * driver detach. + * + * This is equivalent to devm_fwnode_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. + * + * On successful request the GPIO pin is configured in accordance with + * provided @flags. + */ +struct gpio_desc *devm_fwnode_gpiod_get_optional(struct device *dev, + struct fwnode_handle *fwnode, + const char *con_id, + enum gpiod_flags flags, + const char *label) +{ + return devm_fwnode_gpiod_get_index_optional(dev, fwnode, con_id, 0, + flags, label); +} +EXPORT_SYMBOL_GPL(devm_fwnode_gpiod_get_optional); + /** * devm_fwnode_gpiod_get_index - get a GPIO descriptor from a given node * @dev: GPIO consumer @@ -226,6 +257,46 @@ struct gpio_desc *devm_fwnode_gpiod_get_index(struct device *dev, } EXPORT_SYMBOL_GPL(devm_fwnode_gpiod_get_index); +/** + * devm_fwnode_gpiod_get_index_optional - Resource-managed fwnode_gpiod_get_index() + * for optional GPIO + * @dev: GPIO consumer + * @fwnode: firmware node containing GPIO reference + * @con_id: function within the GPIO consumer + * @index: index of the GPIO to obtain in the consumer + * @flags: GPIO initialization flags + * @label: label to attach to the requested GPIO + * + * GPIO descriptors returned from this function are automatically disposed on + * driver detach. + * + * This is equivalent to devm_fwnode_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. + * + * On successful request the GPIO pin is configured in accordance with + * provided @flags. + */ +struct gpio_desc *devm_fwnode_gpiod_get_index_optional(struct device *dev, + struct fwnode_handle *fwnode, + const char *con_id, int index, + enum gpiod_flags flags, + const char *label) +{ + struct gpio_desc *desc; + + desc = devm_fwnode_gpiod_get_index(dev, fwnode, con_id, index, flags, + label); + if (IS_ERR(desc)) { + if (PTR_ERR(desc) == -ENOENT) + return NULL; + } + + return desc; +} +EXPORT_SYMBOL_GPL(devm_fwnode_gpiod_get_index_optional); + /** * devm_gpiod_get_index_optional - Resource-managed gpiod_get_index_optional() * @dev: GPIO consumer diff --git a/include/linux/gpio/consumer.h b/include/linux/gpio/consumer.h index 901aab89d025..7854d80b1e9a 100644 --- a/include/linux/gpio/consumer.h +++ b/include/linux/gpio/consumer.h @@ -183,11 +183,21 @@ struct gpio_desc *fwnode_gpiod_get_index(struct fwnode_handle *fwnode, const char *con_id, int index, enum gpiod_flags flags, const char *label); +struct gpio_desc *devm_fwnode_gpiod_get_optional(struct device *dev, + struct fwnode_handle *fwnode, + const char *con_id, + enum gpiod_flags flags, + const char *label); struct gpio_desc *devm_fwnode_gpiod_get_index(struct device *dev, struct fwnode_handle *child, const char *con_id, int index, enum gpiod_flags flags, const char *label); +struct gpio_desc *devm_fwnode_gpiod_get_index_optional(struct device *dev, + struct fwnode_handle *fwnode, + const char *con_id, int index, + enum gpiod_flags flags, + const char *label); #else /* CONFIG_GPIOLIB */ @@ -562,6 +572,16 @@ struct gpio_desc *fwnode_gpiod_get_index(struct fwnode_handle *fwnode, return ERR_PTR(-ENOSYS); } +static inline +struct gpio_desc *devm_fwnode_gpiod_get_optional(struct device *dev, + struct fwnode_handle *fwnode, + const char *con_id, + enum gpiod_flags flags, + const char *label) +{ + return NULL; +} + static inline struct gpio_desc *devm_fwnode_gpiod_get_index(struct device *dev, struct fwnode_handle *fwnode, @@ -572,6 +592,16 @@ struct gpio_desc *devm_fwnode_gpiod_get_index(struct device *dev, return ERR_PTR(-ENOSYS); } +static inline +struct gpio_desc *devm_fwnode_gpiod_get_index_optional(struct device *dev, + struct fwnode_handle *fwnode, + const char *con_id, int index, + enum gpiod_flags flags, + const char *label) +{ + return NULL; +} + #endif /* CONFIG_GPIOLIB */ static inline
Add devm_fwnode_gpiod_get_optional() and devm_fwnode_gpiod_get_index_optional() helpers, similar to regular devm_gpiod optional versions. Drivers getting GPIOs from a firmware node might use it to remove some boilerplate code. Signed-off-by: Krzysztof Kozlowski <krzk@kernel.org> --- Changes since v2: 1. Return NULL Changes since v1: 1. New patch --- drivers/gpio/gpiolib-devres.c | 71 +++++++++++++++++++++++++++++++++++ include/linux/gpio/consumer.h | 30 +++++++++++++++ 2 files changed, 101 insertions(+)