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

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


Signed-off-by: default avatarLinus Walleij <linus.walleij@linaro.org>
parent 926cf596
Loading
Loading
Loading
Loading
+28 −0
Original line number Diff line number Diff line
@@ -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;