Commit e0e489aa authored by Patrick Williams's avatar Patrick Williams Committed by Greg Kroah-Hartman

pinctrl: armada-37xx: fix control of pins 32 and up

commit 20504fa1 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: 5715092a ("pinctrl: armada-37xx: Add gpio support")
Signed-off-by: default avatarPatrick Williams <alpawi@amazon.com>
Acked-by: default avatarGregory CLEMENT <gregory.clement@bootlin.com>
Cc: <stable@vger.kernel.org>
Link: https://lore.kernel.org/r/20191001154634.96165-1-alpawi@amazon.comSigned-off-by: default avatarLinus Walleij <linus.walleij@linaro.org>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 5e9d7180
...@@ -218,11 +218,11 @@ static const struct armada_37xx_pin_data armada_37xx_pin_sb = { ...@@ -218,11 +218,11 @@ static const struct armada_37xx_pin_data armada_37xx_pin_sb = {
}; };
static inline void armada_37xx_update_reg(unsigned int *reg, static inline void armada_37xx_update_reg(unsigned int *reg,
unsigned int offset) unsigned int *offset)
{ {
/* We never have more than 2 registers */ /* We never have more than 2 registers */
if (offset >= GPIO_PER_REG) { if (*offset >= GPIO_PER_REG) {
offset -= GPIO_PER_REG; *offset -= GPIO_PER_REG;
*reg += sizeof(u32); *reg += sizeof(u32);
} }
} }
...@@ -373,7 +373,7 @@ static inline void armada_37xx_irq_update_reg(unsigned int *reg, ...@@ -373,7 +373,7 @@ static inline void armada_37xx_irq_update_reg(unsigned int *reg,
{ {
int offset = irqd_to_hwirq(d); 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, static int armada_37xx_gpio_direction_input(struct gpio_chip *chip,
...@@ -383,7 +383,7 @@ static int armada_37xx_gpio_direction_input(struct gpio_chip *chip, ...@@ -383,7 +383,7 @@ static int armada_37xx_gpio_direction_input(struct gpio_chip *chip,
unsigned int reg = OUTPUT_EN; unsigned int reg = OUTPUT_EN;
unsigned int mask; unsigned int mask;
armada_37xx_update_reg(&reg, offset); armada_37xx_update_reg(&reg, &offset);
mask = BIT(offset); mask = BIT(offset);
return regmap_update_bits(info->regmap, reg, mask, 0); return regmap_update_bits(info->regmap, reg, mask, 0);
...@@ -396,7 +396,7 @@ static int armada_37xx_gpio_get_direction(struct gpio_chip *chip, ...@@ -396,7 +396,7 @@ static int armada_37xx_gpio_get_direction(struct gpio_chip *chip,
unsigned int reg = OUTPUT_EN; unsigned int reg = OUTPUT_EN;
unsigned int val, mask; unsigned int val, mask;
armada_37xx_update_reg(&reg, offset); armada_37xx_update_reg(&reg, &offset);
mask = BIT(offset); mask = BIT(offset);
regmap_read(info->regmap, reg, &val); regmap_read(info->regmap, reg, &val);
...@@ -410,7 +410,7 @@ static int armada_37xx_gpio_direction_output(struct gpio_chip *chip, ...@@ -410,7 +410,7 @@ static int armada_37xx_gpio_direction_output(struct gpio_chip *chip,
unsigned int reg = OUTPUT_EN; unsigned int reg = OUTPUT_EN;
unsigned int mask, val, ret; unsigned int mask, val, ret;
armada_37xx_update_reg(&reg, offset); armada_37xx_update_reg(&reg, &offset);
mask = BIT(offset); mask = BIT(offset);
ret = regmap_update_bits(info->regmap, reg, mask, mask); ret = regmap_update_bits(info->regmap, reg, mask, mask);
...@@ -431,7 +431,7 @@ static int armada_37xx_gpio_get(struct gpio_chip *chip, unsigned int offset) ...@@ -431,7 +431,7 @@ static int armada_37xx_gpio_get(struct gpio_chip *chip, unsigned int offset)
unsigned int reg = INPUT_VAL; unsigned int reg = INPUT_VAL;
unsigned int val, mask; unsigned int val, mask;
armada_37xx_update_reg(&reg, offset); armada_37xx_update_reg(&reg, &offset);
mask = BIT(offset); mask = BIT(offset);
regmap_read(info->regmap, reg, &val); regmap_read(info->regmap, reg, &val);
...@@ -446,7 +446,7 @@ static void armada_37xx_gpio_set(struct gpio_chip *chip, unsigned int offset, ...@@ -446,7 +446,7 @@ static void armada_37xx_gpio_set(struct gpio_chip *chip, unsigned int offset,
unsigned int reg = OUTPUT_VAL; unsigned int reg = OUTPUT_VAL;
unsigned int mask, val; unsigned int mask, val;
armada_37xx_update_reg(&reg, offset); armada_37xx_update_reg(&reg, &offset);
mask = BIT(offset); mask = BIT(offset);
val = value ? mask : 0; val = value ? mask : 0;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment