gpiolib: add devm_gpiod_get_array and devm_gpiod_put_array functions
Add device managed variants of gpiod_get_array() / gpiod_put_array() functions for conveniently obtaining and disposing of an entire array of GPIOs with one function call. Signed-off-by: Rojhalat Ibrahim <imr@rtschenk.de> Reviewed-by: Alexandre Courbot <acourbot@nvidia.com> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
This commit is contained in:
parent
6685852732
commit
331758eef8
|
@ -102,11 +102,19 @@ Device-managed variants of these functions are also defined:
|
|||
const char *con_id,
|
||||
enum gpiod_flags flags)
|
||||
|
||||
struct gpio_desc * devm_gpiod_get_index_optional(struct device *dev,
|
||||
struct gpio_desc *devm_gpiod_get_index_optional(struct device *dev,
|
||||
const char *con_id,
|
||||
unsigned int index,
|
||||
enum gpiod_flags flags)
|
||||
|
||||
struct gpio_descs *devm_gpiod_get_array(struct device *dev,
|
||||
const char *con_id,
|
||||
enum gpiod_flags flags)
|
||||
|
||||
struct gpio_descs *devm_gpiod_get_array_optional(struct device *dev,
|
||||
const char *con_id,
|
||||
enum gpiod_flags flags)
|
||||
|
||||
A GPIO descriptor can be disposed of using the gpiod_put() function:
|
||||
|
||||
void gpiod_put(struct gpio_desc *desc)
|
||||
|
@ -119,10 +127,12 @@ It is strictly forbidden to use a descriptor after calling these functions.
|
|||
It is also not allowed to individually release descriptors (using gpiod_put())
|
||||
from an array acquired with gpiod_get_array().
|
||||
|
||||
The device-managed variant is, unsurprisingly:
|
||||
The device-managed variants are, unsurprisingly:
|
||||
|
||||
void devm_gpiod_put(struct device *dev, struct gpio_desc *desc)
|
||||
|
||||
void devm_gpiod_put_array(struct device *dev, struct gpio_descs *descs)
|
||||
|
||||
|
||||
Using GPIOs
|
||||
===========
|
||||
|
|
|
@ -35,6 +35,20 @@ static int devm_gpiod_match(struct device *dev, void *res, void *data)
|
|||
return *this == *gpio;
|
||||
}
|
||||
|
||||
static void devm_gpiod_release_array(struct device *dev, void *res)
|
||||
{
|
||||
struct gpio_descs **descs = res;
|
||||
|
||||
gpiod_put_array(*descs);
|
||||
}
|
||||
|
||||
static int devm_gpiod_match_array(struct device *dev, void *res, void *data)
|
||||
{
|
||||
struct gpio_descs **this = res, **gpios = data;
|
||||
|
||||
return *this == *gpios;
|
||||
}
|
||||
|
||||
/**
|
||||
* devm_gpiod_get - Resource-managed gpiod_get()
|
||||
* @dev: GPIO consumer
|
||||
|
@ -185,6 +199,66 @@ struct gpio_desc *__must_check __devm_gpiod_get_index_optional(struct device *de
|
|||
}
|
||||
EXPORT_SYMBOL(__devm_gpiod_get_index_optional);
|
||||
|
||||
/**
|
||||
* devm_gpiod_get_array - Resource-managed gpiod_get_array()
|
||||
* @dev: GPIO consumer
|
||||
* @con_id: function within the GPIO consumer
|
||||
* @flags: optional GPIO initialization flags
|
||||
*
|
||||
* Managed gpiod_get_array(). GPIO descriptors returned from this function are
|
||||
* automatically disposed on driver detach. See gpiod_get_array() for detailed
|
||||
* information about behavior and return values.
|
||||
*/
|
||||
struct gpio_descs *__must_check devm_gpiod_get_array(struct device *dev,
|
||||
const char *con_id,
|
||||
enum gpiod_flags flags)
|
||||
{
|
||||
struct gpio_descs **dr;
|
||||
struct gpio_descs *descs;
|
||||
|
||||
dr = devres_alloc(devm_gpiod_release_array,
|
||||
sizeof(struct gpio_descs *), GFP_KERNEL);
|
||||
if (!dr)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
descs = gpiod_get_array(dev, con_id, flags);
|
||||
if (IS_ERR(descs)) {
|
||||
devres_free(dr);
|
||||
return descs;
|
||||
}
|
||||
|
||||
*dr = descs;
|
||||
devres_add(dev, dr);
|
||||
|
||||
return descs;
|
||||
}
|
||||
EXPORT_SYMBOL(devm_gpiod_get_array);
|
||||
|
||||
/**
|
||||
* devm_gpiod_get_array_optional - Resource-managed gpiod_get_array_optional()
|
||||
* @dev: GPIO consumer
|
||||
* @con_id: function within the GPIO consumer
|
||||
* @flags: optional GPIO initialization flags
|
||||
*
|
||||
* Managed gpiod_get_array_optional(). GPIO descriptors returned from this
|
||||
* function are automatically disposed on driver detach.
|
||||
* See gpiod_get_array_optional() for detailed information about behavior and
|
||||
* return values.
|
||||
*/
|
||||
struct gpio_descs *__must_check
|
||||
devm_gpiod_get_array_optional(struct device *dev, const char *con_id,
|
||||
enum gpiod_flags flags)
|
||||
{
|
||||
struct gpio_descs *descs;
|
||||
|
||||
descs = devm_gpiod_get_array(dev, con_id, flags);
|
||||
if (IS_ERR(descs) && (PTR_ERR(descs) == -ENOENT))
|
||||
return NULL;
|
||||
|
||||
return descs;
|
||||
}
|
||||
EXPORT_SYMBOL(devm_gpiod_get_array_optional);
|
||||
|
||||
/**
|
||||
* devm_gpiod_put - Resource-managed gpiod_put()
|
||||
* @desc: GPIO descriptor to dispose of
|
||||
|
@ -200,6 +274,21 @@ void devm_gpiod_put(struct device *dev, struct gpio_desc *desc)
|
|||
}
|
||||
EXPORT_SYMBOL(devm_gpiod_put);
|
||||
|
||||
/**
|
||||
* devm_gpiod_put_array - Resource-managed gpiod_put_array()
|
||||
* @descs: GPIO descriptor array to dispose of
|
||||
*
|
||||
* Dispose of an array of GPIO descriptors obtained with devm_gpiod_get_array().
|
||||
* Normally this function will not be called as the GPIOs will be disposed of
|
||||
* by the resource management code.
|
||||
*/
|
||||
void devm_gpiod_put_array(struct device *dev, struct gpio_descs *descs)
|
||||
{
|
||||
WARN_ON(devres_release(dev, devm_gpiod_release_array,
|
||||
devm_gpiod_match_array, &descs));
|
||||
}
|
||||
EXPORT_SYMBOL(devm_gpiod_put_array);
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -83,7 +83,14 @@ struct gpio_desc *__must_check __devm_gpiod_get_optional(struct device *dev,
|
|||
struct gpio_desc *__must_check
|
||||
__devm_gpiod_get_index_optional(struct device *dev, const char *con_id,
|
||||
unsigned int index, enum gpiod_flags flags);
|
||||
struct gpio_descs *__must_check devm_gpiod_get_array(struct device *dev,
|
||||
const char *con_id,
|
||||
enum gpiod_flags flags);
|
||||
struct gpio_descs *__must_check
|
||||
devm_gpiod_get_array_optional(struct device *dev, const char *con_id,
|
||||
enum gpiod_flags flags);
|
||||
void devm_gpiod_put(struct device *dev, struct gpio_desc *desc);
|
||||
void devm_gpiod_put_array(struct device *dev, struct gpio_descs *descs);
|
||||
|
||||
int gpiod_get_direction(struct gpio_desc *desc);
|
||||
int gpiod_direction_input(struct gpio_desc *desc);
|
||||
|
@ -228,6 +235,20 @@ __devm_gpiod_get_index_optional(struct device *dev, const char *con_id,
|
|||
return ERR_PTR(-ENOSYS);
|
||||
}
|
||||
|
||||
static inline struct gpio_descs *__must_check
|
||||
devm_gpiod_get_array(struct device *dev, const char *con_id,
|
||||
enum gpiod_flags flags)
|
||||
{
|
||||
return ERR_PTR(-ENOSYS);
|
||||
}
|
||||
|
||||
static inline struct gpio_descs *__must_check
|
||||
devm_gpiod_get_array_optional(struct device *dev, const char *con_id,
|
||||
enum gpiod_flags flags)
|
||||
{
|
||||
return ERR_PTR(-ENOSYS);
|
||||
}
|
||||
|
||||
static inline void devm_gpiod_put(struct device *dev, struct gpio_desc *desc)
|
||||
{
|
||||
might_sleep();
|
||||
|
@ -236,6 +257,15 @@ static inline void devm_gpiod_put(struct device *dev, struct gpio_desc *desc)
|
|||
WARN_ON(1);
|
||||
}
|
||||
|
||||
static inline void devm_gpiod_put_array(struct device *dev,
|
||||
struct gpio_descs *descs)
|
||||
{
|
||||
might_sleep();
|
||||
|
||||
/* GPIO can never have been requested */
|
||||
WARN_ON(1);
|
||||
}
|
||||
|
||||
|
||||
static inline int gpiod_get_direction(const struct gpio_desc *desc)
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue