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: 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>
This commit is contained in:
parent
54ecb8f702
commit
20504fa1d2
@ -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(®, offset);
|
||||
armada_37xx_update_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(®, offset);
|
||||
armada_37xx_update_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(®, offset);
|
||||
armada_37xx_update_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(®, offset);
|
||||
armada_37xx_update_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(®, offset);
|
||||
armada_37xx_update_reg(®, &offset);
|
||||
mask = BIT(offset);
|
||||
val = value ? mask : 0;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user