diff options
author | Gabor Juhos <j4g8y7@gmail.com> | 2025-05-14 21:18:33 +0200 |
---|---|---|
committer | Linus Walleij <linus.walleij@linaro.org> | 2025-05-15 00:18:14 +0200 |
commit | e6ebd4942981f8ad37189bbb36a3c8495e21ef4c (patch) | |
tree | 566da11522533b68e89c15c4ff35c914f8ba0fb3 | |
parent | 947c93eb29c2a581c0b0b6d5f21af3c2b7ff6d25 (diff) |
pinctrl: armada-37xx: set GPIO output value before setting direction
Changing the direction before updating the output value in the
OUTPUT_VAL register may result in a glitch on the output line
if the previous value in the OUTPUT_VAL register is different
from the one we want to set.
In order to avoid that, update the output value before changing
the direction.
Cc: stable@vger.kernel.org
Fixes: 6702abb3bf23 ("pinctrl: armada-37xx: Fix direction_output() callback behavior")
Signed-off-by: Imre Kaloz <kaloz@openwrt.org>
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Signed-off-by: Gabor Juhos <j4g8y7@gmail.com>
Link: https://lore.kernel.org/20250514-pinctrl-a37xx-fixes-v2-2-07e9ac1ab737@gmail.com
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
-rw-r--r-- | drivers/pinctrl/mvebu/pinctrl-armada-37xx.c | 15 |
1 files changed, 7 insertions, 8 deletions
diff --git a/drivers/pinctrl/mvebu/pinctrl-armada-37xx.c b/drivers/pinctrl/mvebu/pinctrl-armada-37xx.c index 43034d292926..79f9c08e5039 100644 --- a/drivers/pinctrl/mvebu/pinctrl-armada-37xx.c +++ b/drivers/pinctrl/mvebu/pinctrl-armada-37xx.c @@ -417,23 +417,22 @@ static int armada_37xx_gpio_direction_output(struct gpio_chip *chip, unsigned int offset, int value) { struct armada_37xx_pinctrl *info = gpiochip_get_data(chip); - unsigned int val_offset = offset; - unsigned int reg = OUTPUT_EN; + unsigned int en_offset = offset; + unsigned int reg = OUTPUT_VAL; unsigned int mask, val, ret; armada_37xx_update_reg(®, &offset); mask = BIT(offset); + val = value ? mask : 0; - ret = regmap_update_bits(info->regmap, reg, mask, mask); - + ret = regmap_update_bits(info->regmap, reg, mask, val); if (ret) return ret; - reg = OUTPUT_VAL; - armada_37xx_update_reg(®, &val_offset); + reg = OUTPUT_EN; + armada_37xx_update_reg(®, &en_offset); - val = value ? mask : 0; - regmap_update_bits(info->regmap, reg, mask, val); + regmap_update_bits(info->regmap, reg, mask, mask); return 0; } |