gpio: Introduce ->get_multiple callback
SPI-attached GPIO controllers typically read out all inputs in one go. If callers desire the values of multipe inputs, ideally a single readout should take place to return the desired values. However the current driver API only offers a ->get callback but no ->get_multiple (unlike ->set_multiple, which is present). Thus, to read multiple inputs, a full readout needs to be performed for every single value (barring driver-internal caching), which is inefficient. In fact, the lack of a ->get_multiple callback has been bemoaned repeatedly by the gpio subsystem maintainer: http://www.spinics.net/lists/linux-gpio/msg10571.html http://www.spinics.net/lists/devicetree/msg121734.html Introduce the missing callback. Add corresponding consumer functions such as gpiod_get_array_value(). Amend linehandle_ioctl() to take advantage of the newly added infrastructure. Update the documentation. Cc: Rojhalat Ibrahim <imr@rtschenk.de> Signed-off-by: Lukas Wunner <lukas@wunner.de> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
This commit is contained in:

committed by
Linus Walleij

parent
5307e2ad69
commit
eec1d566cd
@@ -99,10 +99,15 @@ int gpiod_direction_output_raw(struct gpio_desc *desc, int value);
|
||||
|
||||
/* Value get/set from non-sleeping context */
|
||||
int gpiod_get_value(const struct gpio_desc *desc);
|
||||
int gpiod_get_array_value(unsigned int array_size,
|
||||
struct gpio_desc **desc_array, int *value_array);
|
||||
void gpiod_set_value(struct gpio_desc *desc, int value);
|
||||
void gpiod_set_array_value(unsigned int array_size,
|
||||
struct gpio_desc **desc_array, int *value_array);
|
||||
int gpiod_get_raw_value(const struct gpio_desc *desc);
|
||||
int gpiod_get_raw_array_value(unsigned int array_size,
|
||||
struct gpio_desc **desc_array,
|
||||
int *value_array);
|
||||
void gpiod_set_raw_value(struct gpio_desc *desc, int value);
|
||||
void gpiod_set_raw_array_value(unsigned int array_size,
|
||||
struct gpio_desc **desc_array,
|
||||
@@ -110,11 +115,17 @@ void gpiod_set_raw_array_value(unsigned int array_size,
|
||||
|
||||
/* Value get/set from sleeping context */
|
||||
int gpiod_get_value_cansleep(const struct gpio_desc *desc);
|
||||
int gpiod_get_array_value_cansleep(unsigned int array_size,
|
||||
struct gpio_desc **desc_array,
|
||||
int *value_array);
|
||||
void gpiod_set_value_cansleep(struct gpio_desc *desc, int value);
|
||||
void gpiod_set_array_value_cansleep(unsigned int array_size,
|
||||
struct gpio_desc **desc_array,
|
||||
int *value_array);
|
||||
int gpiod_get_raw_value_cansleep(const struct gpio_desc *desc);
|
||||
int gpiod_get_raw_array_value_cansleep(unsigned int array_size,
|
||||
struct gpio_desc **desc_array,
|
||||
int *value_array);
|
||||
void gpiod_set_raw_value_cansleep(struct gpio_desc *desc, int value);
|
||||
void gpiod_set_raw_array_value_cansleep(unsigned int array_size,
|
||||
struct gpio_desc **desc_array,
|
||||
@@ -305,6 +316,14 @@ static inline int gpiod_get_value(const struct gpio_desc *desc)
|
||||
WARN_ON(1);
|
||||
return 0;
|
||||
}
|
||||
static inline int gpiod_get_array_value(unsigned int array_size,
|
||||
struct gpio_desc **desc_array,
|
||||
int *value_array)
|
||||
{
|
||||
/* GPIO can never have been requested */
|
||||
WARN_ON(1);
|
||||
return 0;
|
||||
}
|
||||
static inline void gpiod_set_value(struct gpio_desc *desc, int value)
|
||||
{
|
||||
/* GPIO can never have been requested */
|
||||
@@ -323,6 +342,14 @@ static inline int gpiod_get_raw_value(const struct gpio_desc *desc)
|
||||
WARN_ON(1);
|
||||
return 0;
|
||||
}
|
||||
static inline int gpiod_get_raw_array_value(unsigned int array_size,
|
||||
struct gpio_desc **desc_array,
|
||||
int *value_array)
|
||||
{
|
||||
/* GPIO can never have been requested */
|
||||
WARN_ON(1);
|
||||
return 0;
|
||||
}
|
||||
static inline void gpiod_set_raw_value(struct gpio_desc *desc, int value)
|
||||
{
|
||||
/* GPIO can never have been requested */
|
||||
@@ -342,6 +369,14 @@ static inline int gpiod_get_value_cansleep(const struct gpio_desc *desc)
|
||||
WARN_ON(1);
|
||||
return 0;
|
||||
}
|
||||
static inline int gpiod_get_array_value_cansleep(unsigned int array_size,
|
||||
struct gpio_desc **desc_array,
|
||||
int *value_array)
|
||||
{
|
||||
/* GPIO can never have been requested */
|
||||
WARN_ON(1);
|
||||
return 0;
|
||||
}
|
||||
static inline void gpiod_set_value_cansleep(struct gpio_desc *desc, int value)
|
||||
{
|
||||
/* GPIO can never have been requested */
|
||||
@@ -360,6 +395,14 @@ static inline int gpiod_get_raw_value_cansleep(const struct gpio_desc *desc)
|
||||
WARN_ON(1);
|
||||
return 0;
|
||||
}
|
||||
static inline int gpiod_get_raw_array_value_cansleep(unsigned int array_size,
|
||||
struct gpio_desc **desc_array,
|
||||
int *value_array)
|
||||
{
|
||||
/* GPIO can never have been requested */
|
||||
WARN_ON(1);
|
||||
return 0;
|
||||
}
|
||||
static inline void gpiod_set_raw_value_cansleep(struct gpio_desc *desc,
|
||||
int value)
|
||||
{
|
||||
|
@@ -35,6 +35,8 @@ struct module;
|
||||
* @direction_input: configures signal "offset" as input, or returns error
|
||||
* @direction_output: configures signal "offset" as output, or returns error
|
||||
* @get: returns value for signal "offset", 0=low, 1=high, or negative error
|
||||
* @get_multiple: reads values for multiple signals defined by "mask" and
|
||||
* stores them in "bits", returns 0 on success or negative error
|
||||
* @set: assigns output value for signal "offset"
|
||||
* @set_multiple: assigns output values for multiple signals defined by "mask"
|
||||
* @set_config: optional hook for all kinds of settings. Uses the same
|
||||
@@ -125,6 +127,9 @@ struct gpio_chip {
|
||||
unsigned offset, int value);
|
||||
int (*get)(struct gpio_chip *chip,
|
||||
unsigned offset);
|
||||
int (*get_multiple)(struct gpio_chip *chip,
|
||||
unsigned long *mask,
|
||||
unsigned long *bits);
|
||||
void (*set)(struct gpio_chip *chip,
|
||||
unsigned offset, int value);
|
||||
void (*set_multiple)(struct gpio_chip *chip,
|
||||
|
Reference in New Issue
Block a user