gpiolib: allow simultaneous setting of multiple GPIO outputs
Introduce new functions gpiod_set_array & gpiod_set_raw_array to the consumer interface which allow setting multiple outputs with just one function call. Also add an optional set_multiple function to the driver interface. Without an implementation of that function in the chip driver outputs are set sequentially. Implementing the set_multiple function in a chip driver allows for: - Improved performance for certain use cases. The original motivation for this was the task of configuring an FPGA. In that specific case, where 9 GPIO lines have to be set many times, configuration time goes down from 48 s to 20 s when using the new function. - Simultaneous glitch-free setting of multiple pins on any kind of parallel bus attached to GPIOs provided they all reside on the same chip and bank. Limitations: Performance is only improved for normal high-low outputs. Open drain and open source outputs are always set separately from each other. Those kinds of outputs could probably be accelerated in a similar way if we could forgo the error checking when setting GPIO directions. Change log: v6: - rebase on current linux-gpio devel branch v5: - check can_sleep property per chip - remove superfluous checks - supplement documentation v4: - add gpiod_set_array function for setting logical values - change interface of the set_multiple driver function to use unsigned long as type for the bit fields - use generic bitops (which also use unsigned long for bit fields) - do not use ARCH_NR_GPIOS any more v3: - add documentation - change commit message v2: - use descriptor interface - allow arbitrary groups of GPIOs spanning multiple chips Signed-off-by: Rojhalat Ibrahim <imr@rtschenk.de> Reviewed-by: Alexandre Courbot <acourbot@nvidia.com> Reviewed-by: Mark Brown <broonie@linaro.org> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
This commit is contained in:

committed by
Linus Walleij

parent
b5b7b48743
commit
5f42424354
@@ -32,6 +32,7 @@ struct seq_file;
|
||||
* @get: returns value for signal "offset"; for output signals this
|
||||
* returns either the value actually sensed, or zero
|
||||
* @set: assigns output value for signal "offset"
|
||||
* @set_multiple: assigns output values for multiple signals defined by "mask"
|
||||
* @set_debounce: optional hook for setting debounce time for specified gpio in
|
||||
* interrupt triggered gpio chips
|
||||
* @to_irq: optional hook supporting non-static gpio_to_irq() mappings;
|
||||
@@ -89,6 +90,9 @@ struct gpio_chip {
|
||||
unsigned offset);
|
||||
void (*set)(struct gpio_chip *chip,
|
||||
unsigned offset, int value);
|
||||
void (*set_multiple)(struct gpio_chip *chip,
|
||||
unsigned long *mask,
|
||||
unsigned long *bits);
|
||||
int (*set_debounce)(struct gpio_chip *chip,
|
||||
unsigned offset,
|
||||
unsigned debounce);
|
||||
|
Reference in New Issue
Block a user