Commit 20504fa1 authored by Patrick Williams's avatar Patrick Williams Committed by Linus Walleij
Browse files

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



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.com


Signed-off-by: default avatarLinus Walleij <linus.walleij@linaro.org>
parent 54ecb8f7
Loading
Loading
Loading
Loading
+9 −9
Original line number Diff line number Diff line
@@ -221,11 +221,11 @@ static const struct armada_37xx_pin_data armada_37xx_pin_sb = {
};

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);
	}
}
@@ -376,7 +376,7 @@ static inline void armada_37xx_irq_update_reg(unsigned int *reg,
{
	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,
@@ -386,7 +386,7 @@ static int armada_37xx_gpio_direction_input(struct gpio_chip *chip,
	unsigned int reg = OUTPUT_EN;
	unsigned int mask;

	armada_37xx_update_reg(&reg, offset);
	armada_37xx_update_reg(&reg, &offset);
	mask = BIT(offset);

	return regmap_update_bits(info->regmap, reg, mask, 0);
@@ -399,7 +399,7 @@ static int armada_37xx_gpio_get_direction(struct gpio_chip *chip,
	unsigned int reg = OUTPUT_EN;
	unsigned int val, mask;

	armada_37xx_update_reg(&reg, offset);
	armada_37xx_update_reg(&reg, &offset);
	mask = BIT(offset);
	regmap_read(info->regmap, reg, &val);

@@ -413,7 +413,7 @@ static int armada_37xx_gpio_direction_output(struct gpio_chip *chip,
	unsigned int reg = OUTPUT_EN;
	unsigned int mask, val, ret;

	armada_37xx_update_reg(&reg, offset);
	armada_37xx_update_reg(&reg, &offset);
	mask = BIT(offset);

	ret = regmap_update_bits(info->regmap, reg, mask, mask);
@@ -434,7 +434,7 @@ static int armada_37xx_gpio_get(struct gpio_chip *chip, unsigned int offset)
	unsigned int reg = INPUT_VAL;
	unsigned int val, mask;

	armada_37xx_update_reg(&reg, offset);
	armada_37xx_update_reg(&reg, &offset);
	mask = BIT(offset);

	regmap_read(info->regmap, reg, &val);
@@ -449,7 +449,7 @@ static void armada_37xx_gpio_set(struct gpio_chip *chip, unsigned int offset,
	unsigned int reg = OUTPUT_VAL;
	unsigned int mask, val;

	armada_37xx_update_reg(&reg, offset);
	armada_37xx_update_reg(&reg, &offset);
	mask = BIT(offset);
	val = value ? mask : 0;