diff options
author | Geert Uytterhoeven <geert+renesas@glider.be> | 2020-10-28 15:15:04 +0100 |
---|---|---|
committer | Bartosz Golaszewski <bgolaszewski@baylibre.com> | 2020-10-30 15:57:41 +0100 |
commit | 183245c4f204bc1458163388c8de8ddfc032a607 (patch) | |
tree | 9ae878bb45a64e2722c7785d0c6582e2044b12d8 /drivers/gpio/gpio-rcar.c | |
parent | 208c80f14b5935edb9f3881c489dcc83742d8916 (diff) |
gpio: rcar: Implement gpio_chip.get_multiple()
Add support for getting the state of multiple pins using a minimum of
register reads.
Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>
Diffstat (limited to 'drivers/gpio/gpio-rcar.c')
-rw-r--r-- | drivers/gpio/gpio-rcar.c | 30 |
1 files changed, 30 insertions, 0 deletions
diff --git a/drivers/gpio/gpio-rcar.c b/drivers/gpio/gpio-rcar.c index b33d1a2076ea..0b572dbc4a36 100644 --- a/drivers/gpio/gpio-rcar.c +++ b/drivers/gpio/gpio-rcar.c @@ -310,6 +310,35 @@ static int gpio_rcar_get(struct gpio_chip *chip, unsigned offset) return !!(gpio_rcar_read(p, INDT) & bit); } +static int gpio_rcar_get_multiple(struct gpio_chip *chip, unsigned long *mask, + unsigned long *bits) +{ + struct gpio_rcar_priv *p = gpiochip_get_data(chip); + u32 bankmask, outputs, m, val = 0; + unsigned long flags; + + bankmask = mask[0] & GENMASK(chip->ngpio - 1, 0); + if (chip->valid_mask) + bankmask &= chip->valid_mask[0]; + + if (!bankmask) + return 0; + + spin_lock_irqsave(&p->lock, flags); + outputs = gpio_rcar_read(p, INOUTSEL); + m = outputs & bankmask; + if (m) + val |= gpio_rcar_read(p, OUTDT) & m; + + m = ~outputs & bankmask; + if (m) + val |= gpio_rcar_read(p, INDT) & m; + spin_unlock_irqrestore(&p->lock, flags); + + bits[0] = val; + return 0; +} + static void gpio_rcar_set(struct gpio_chip *chip, unsigned offset, int value) { struct gpio_rcar_priv *p = gpiochip_get_data(chip); @@ -478,6 +507,7 @@ static int gpio_rcar_probe(struct platform_device *pdev) gpio_chip->get_direction = gpio_rcar_get_direction; gpio_chip->direction_input = gpio_rcar_direction_input; gpio_chip->get = gpio_rcar_get; + gpio_chip->get_multiple = gpio_rcar_get_multiple; gpio_chip->direction_output = gpio_rcar_direction_output; gpio_chip->set = gpio_rcar_set; gpio_chip->set_multiple = gpio_rcar_set_multiple; |