| From 20504fa1d2ffd5d03cdd9dc9c9dd4ed4579b97ef Mon Sep 17 00:00:00 2001 |
| From: Patrick Williams <alpawi@amazon.com> |
| Date: Tue, 1 Oct 2019 10:46:31 -0500 |
| Subject: pinctrl: armada-37xx: fix control of pins 32 and up |
| |
| From: Patrick Williams <alpawi@amazon.com> |
| |
| commit 20504fa1d2ffd5d03cdd9dc9c9dd4ed4579b97ef upstream. |
| |
| The 37xx configuration registers are only 32 bits long, so |
| pins 32-35 spill over into the next register. The calculation |
| for the register address was done, but the bitmask was not, so |
| any configuration to pin 32 or above resulted in a bitmask that |
| overflowed and performed no action. |
| |
| Fix the register / offset calculation to also adjust the offset. |
| |
| Fixes: 5715092a458c ("pinctrl: armada-37xx: Add gpio support") |
| Signed-off-by: Patrick Williams <alpawi@amazon.com> |
| Acked-by: Gregory CLEMENT <gregory.clement@bootlin.com> |
| Cc: <stable@vger.kernel.org> |
| Link: https://lore.kernel.org/r/20191001154634.96165-1-alpawi@amazon.com |
| Signed-off-by: Linus Walleij <linus.walleij@linaro.org> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| |
| --- |
| drivers/pinctrl/mvebu/pinctrl-armada-37xx.c | 18 +++++++++--------- |
| 1 file changed, 9 insertions(+), 9 deletions(-) |
| |
| --- a/drivers/pinctrl/mvebu/pinctrl-armada-37xx.c |
| +++ b/drivers/pinctrl/mvebu/pinctrl-armada-37xx.c |
| @@ -205,11 +205,11 @@ static const struct armada_37xx_pin_data |
| }; |
| |
| static inline void armada_37xx_update_reg(unsigned int *reg, |
| - unsigned int offset) |
| + unsigned int *offset) |
| { |
| /* We never have more than 2 registers */ |
| - if (offset >= GPIO_PER_REG) { |
| - offset -= GPIO_PER_REG; |
| + if (*offset >= GPIO_PER_REG) { |
| + *offset -= GPIO_PER_REG; |
| *reg += sizeof(u32); |
| } |
| } |
| @@ -373,7 +373,7 @@ static inline void armada_37xx_irq_updat |
| { |
| int offset = irqd_to_hwirq(d); |
| |
| - armada_37xx_update_reg(reg, offset); |
| + armada_37xx_update_reg(reg, &offset); |
| } |
| |
| static int armada_37xx_gpio_direction_input(struct gpio_chip *chip, |
| @@ -383,7 +383,7 @@ static int armada_37xx_gpio_direction_in |
| unsigned int reg = OUTPUT_EN; |
| unsigned int mask; |
| |
| - armada_37xx_update_reg(®, offset); |
| + armada_37xx_update_reg(®, &offset); |
| mask = BIT(offset); |
| |
| return regmap_update_bits(info->regmap, reg, mask, 0); |
| @@ -396,7 +396,7 @@ static int armada_37xx_gpio_get_directio |
| unsigned int reg = OUTPUT_EN; |
| unsigned int val, mask; |
| |
| - armada_37xx_update_reg(®, offset); |
| + armada_37xx_update_reg(®, &offset); |
| mask = BIT(offset); |
| regmap_read(info->regmap, reg, &val); |
| |
| @@ -410,7 +410,7 @@ static int armada_37xx_gpio_direction_ou |
| unsigned int reg = OUTPUT_EN; |
| unsigned int mask, val, ret; |
| |
| - armada_37xx_update_reg(®, offset); |
| + armada_37xx_update_reg(®, &offset); |
| mask = BIT(offset); |
| |
| ret = regmap_update_bits(info->regmap, reg, mask, mask); |
| @@ -431,7 +431,7 @@ static int armada_37xx_gpio_get(struct g |
| unsigned int reg = INPUT_VAL; |
| unsigned int val, mask; |
| |
| - armada_37xx_update_reg(®, offset); |
| + armada_37xx_update_reg(®, &offset); |
| mask = BIT(offset); |
| |
| regmap_read(info->regmap, reg, &val); |
| @@ -446,7 +446,7 @@ static void armada_37xx_gpio_set(struct |
| unsigned int reg = OUTPUT_VAL; |
| unsigned int mask, val; |
| |
| - armada_37xx_update_reg(®, offset); |
| + armada_37xx_update_reg(®, &offset); |
| mask = BIT(offset); |
| val = value ? mask : 0; |
| |