mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2025-01-20 04:24:13 +00:00
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 d21f4b7ffc22 ("pinctrl: qcom: Avoid glitching lines when we first mux to output") to LPASS pin controller with same justification. Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org> Link: https://lore.kernel.org/r/20230309154949.658380-3-krzysztof.kozlowski@linaro.org Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
This commit is contained in:
parent
926cf596ce
commit
fae1466da9
@ -19,6 +19,8 @@
|
||||
|
||||
#include "pinctrl-lpass-lpi.h"
|
||||
|
||||
#define MAX_NR_GPIO 23
|
||||
#define GPIO_FUNC 0
|
||||
#define MAX_LPI_NUM_CLKS 2
|
||||
|
||||
struct lpi_pinctrl {
|
||||
@ -30,6 +32,7 @@ struct lpi_pinctrl {
|
||||
char __iomem *slew_base;
|
||||
struct clk_bulk_data clks[MAX_LPI_NUM_CLKS];
|
||||
struct mutex slew_access_lock;
|
||||
DECLARE_BITMAP(ever_gpio, MAX_NR_GPIO);
|
||||
const struct lpi_pinctrl_variant_data *data;
|
||||
};
|
||||
|
||||
@ -100,6 +103,28 @@ static int lpi_gpio_set_mux(struct pinctrl_dev *pctldev, unsigned int function,
|
||||
return -EINVAL;
|
||||
|
||||
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);
|
||||
lpi_gpio_write(pctrl, pin, LPI_GPIO_CFG_REG, val);
|
||||
|
||||
@ -394,6 +419,9 @@ int lpi_pinctrl_probe(struct platform_device *pdev)
|
||||
if (!data)
|
||||
return -EINVAL;
|
||||
|
||||
if (WARN_ON(data->npins > MAX_NR_GPIO))
|
||||
return -EINVAL;
|
||||
|
||||
pctrl->data = data;
|
||||
pctrl->dev = &pdev->dev;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user