Commit fae1466d authored by Krzysztof Kozlowski's avatar Krzysztof Kozlowski Committed by Linus Walleij

pinctrl: qcom: lpass-lpi: allow glitch-free output GPIO

When choosing GPIO function for pins, use the same glitch-free method as
main TLMM pinctrl-msm.c driver in msm_pinmux_set_mux().  This replicates
the commit d21f4b7f ("pinctrl: qcom: Avoid glitching lines when we
first mux to output") to LPASS pin controller with same justification.
Signed-off-by: default avatarKrzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
Link: https://lore.kernel.org/r/20230309154949.658380-3-krzysztof.kozlowski@linaro.orgSigned-off-by: default avatarLinus Walleij <linus.walleij@linaro.org>
parent 926cf596
...@@ -19,6 +19,8 @@ ...@@ -19,6 +19,8 @@
#include "pinctrl-lpass-lpi.h" #include "pinctrl-lpass-lpi.h"
#define MAX_NR_GPIO 23
#define GPIO_FUNC 0
#define MAX_LPI_NUM_CLKS 2 #define MAX_LPI_NUM_CLKS 2
struct lpi_pinctrl { struct lpi_pinctrl {
...@@ -30,6 +32,7 @@ struct lpi_pinctrl { ...@@ -30,6 +32,7 @@ struct lpi_pinctrl {
char __iomem *slew_base; char __iomem *slew_base;
struct clk_bulk_data clks[MAX_LPI_NUM_CLKS]; struct clk_bulk_data clks[MAX_LPI_NUM_CLKS];
struct mutex slew_access_lock; struct mutex slew_access_lock;
DECLARE_BITMAP(ever_gpio, MAX_NR_GPIO);
const struct lpi_pinctrl_variant_data *data; const struct lpi_pinctrl_variant_data *data;
}; };
...@@ -100,6 +103,28 @@ static int lpi_gpio_set_mux(struct pinctrl_dev *pctldev, unsigned int function, ...@@ -100,6 +103,28 @@ static int lpi_gpio_set_mux(struct pinctrl_dev *pctldev, unsigned int function,
return -EINVAL; return -EINVAL;
val = lpi_gpio_read(pctrl, pin, LPI_GPIO_CFG_REG); val = lpi_gpio_read(pctrl, pin, LPI_GPIO_CFG_REG);
/*
* If this is the first time muxing to GPIO and the direction is
* output, make sure that we're not going to be glitching the pin
* by reading the current state of the pin and setting it as the
* output.
*/
if (i == GPIO_FUNC && (val & LPI_GPIO_OE_MASK) &&
!test_and_set_bit(group, pctrl->ever_gpio)) {
u32 io_val = lpi_gpio_read(pctrl, group, LPI_GPIO_VALUE_REG);
if (io_val & LPI_GPIO_VALUE_IN_MASK) {
if (!(io_val & LPI_GPIO_VALUE_OUT_MASK))
lpi_gpio_write(pctrl, group, LPI_GPIO_VALUE_REG,
io_val | LPI_GPIO_VALUE_OUT_MASK);
} else {
if (io_val & LPI_GPIO_VALUE_OUT_MASK)
lpi_gpio_write(pctrl, group, LPI_GPIO_VALUE_REG,
io_val & ~LPI_GPIO_VALUE_OUT_MASK);
}
}
u32p_replace_bits(&val, i, LPI_GPIO_FUNCTION_MASK); u32p_replace_bits(&val, i, LPI_GPIO_FUNCTION_MASK);
lpi_gpio_write(pctrl, pin, LPI_GPIO_CFG_REG, val); lpi_gpio_write(pctrl, pin, LPI_GPIO_CFG_REG, val);
...@@ -394,6 +419,9 @@ int lpi_pinctrl_probe(struct platform_device *pdev) ...@@ -394,6 +419,9 @@ int lpi_pinctrl_probe(struct platform_device *pdev)
if (!data) if (!data)
return -EINVAL; return -EINVAL;
if (WARN_ON(data->npins > MAX_NR_GPIO))
return -EINVAL;
pctrl->data = data; pctrl->data = data;
pctrl->dev = &pdev->dev; pctrl->dev = &pdev->dev;
......
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