diff options
author | Linus Walleij <linus.walleij@linaro.org> | 2019-02-22 11:14:44 +0100 |
---|---|---|
committer | Linus Walleij <linus.walleij@linaro.org> | 2019-04-05 00:04:13 +0700 |
commit | f69e00bd21aa6a1961c521b6eb199137fcb8a76a (patch) | |
tree | 0875c21d01d88d2ab5224de0548246f25dcb2d15 /include/linux/gpio | |
parent | Linux 5.1-rc1 (diff) | |
download | wireguard-linux-f69e00bd21aa6a1961c521b6eb199137fcb8a76a.tar.xz wireguard-linux-f69e00bd21aa6a1961c521b6eb199137fcb8a76a.zip |
gpio: mmio: Support two direction registers
It turns out that one specific hardware has two direction
registers: one to set a GPIO line as input and another one
to set a GPIO line as output. So in theory a line can be
configured as input and output at the same time.
Make the MMIO GPIO helper deal with this: store both
registers in the state container, use both in the generic
code if present. Synchronize the input register to the
output register when we register a GPIO chip, with the
output settings taking precedence.
Keep the helper variable to detect inverted direction
semantics (only direction in register) but augment the
code to be more straight-forward for the generic case
when setting the registers.
Fix some flunky with unreadable direction registers at
the same time as we're touching this code.
Cc: David Woods <dwoods@mellanox.com>
Cc: Shravan Kumar Ramani <sramani@mellanox.com>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Diffstat (limited to 'include/linux/gpio')
-rw-r--r-- | include/linux/gpio/driver.h | 15 |
1 files changed, 11 insertions, 4 deletions
diff --git a/include/linux/gpio/driver.h b/include/linux/gpio/driver.h index 01497910f023..95a51794c24a 100644 --- a/include/linux/gpio/driver.h +++ b/include/linux/gpio/driver.h @@ -227,9 +227,13 @@ struct gpio_irq_chip { * @reg_dat: data (in) register for generic GPIO * @reg_set: output set register (out=high) for generic GPIO * @reg_clr: output clear register (out=low) for generic GPIO - * @reg_dir: direction setting register for generic GPIO + * @reg_dir_out: direction out setting register for generic GPIO + * @reg_dir_in: direction in setting register for generic GPIO * @bgpio_dir_inverted: indicates that the direction register is inverted - * (gpiolib private state variable) + * (gpiolib private state variable) this means @reg_dir_in is + * available but not @reg_dir_out. + * @bgpio_dir_unreadable: indicates that the direction register(s) cannot + * be read and we need to rely on out internal state tracking. * @bgpio_bits: number of register bits used for a generic GPIO i.e. * <register width> * 8 * @bgpio_lock: used to lock chip->bgpio_data. Also, this is needed to keep @@ -237,7 +241,8 @@ struct gpio_irq_chip { * @bgpio_data: shadowed data register for generic GPIO to clear/set bits * safely. * @bgpio_dir: shadowed direction register for generic GPIO to clear/set - * direction safely. + * direction safely. A "1" in this word means the line is set as + * output. * * A gpio_chip can help platforms abstract various sources of GPIOs so * they can all be accessed through a common programing interface. @@ -298,8 +303,10 @@ struct gpio_chip { void __iomem *reg_dat; void __iomem *reg_set; void __iomem *reg_clr; - void __iomem *reg_dir; + void __iomem *reg_dir_out; + void __iomem *reg_dir_in; bool bgpio_dir_inverted; + bool bgpio_dir_unreadable; int bgpio_bits; spinlock_t bgpio_lock; unsigned long bgpio_data; |