From: Shawn Guo <shengchao.guo@oss.qualcomm.com>
To: Bartosz Golaszewski <brgl@kernel.org>
Cc: Bjorn Andersson <andersson@kernel.org>,
Neil Armstrong <neil.armstrong@linaro.org>,
Yu Zhang <yu.zhang@oss.qualcomm.com>,
linux-gpio@vger.kernel.org, linux-arm-msm@vger.kernel.org,
linux-kernel@vger.kernel.org, Linus Walleij <linusw@kernel.org>
Subject: Re: [PATCH v2] pinctrl: qcom: spmi-gpio: make direction changes exclusive
Date: Thu, 24 Sep 2026 11:18:05 +0800 [thread overview]
Message-ID: <arSWbexBeEYgBY_x@QCOM-aGQu4IUr3Y> (raw)
In-Reply-To: <CAMRc=MfrBwqdMnT5TynJ0NVBf3OWKF7BSGr1cy4YjyCVrZdX1A@mail.gmail.com>
On Wed, Sep 23, 2026 at 02:07:56AM -0700, Bartosz Golaszewski wrote:
> On Tue, 22 Sep 2026 08:59:08 +0200, Shawn Guo
> <shengchao.guo@oss.qualcomm.com> said:
> > pmic_gpio_populate() seeds pad->input_enabled and pad->output_enabled from
> > the hardware MODE_CTL register, so a pad left in DIGITAL_INPUT or
> > DIGITAL_INPUT_OUTPUT mode by the bootloader starts out with the input
> > buffer enabled. Neither direction callback clears the opposite buffer:
> > .direction_output() only packs PIN_CONFIG_LEVEL, which sets
> > output_enabled, and .direction_input() only packs PIN_CONFIG_INPUT_ENABLE,
> > which sets input_enabled. Requesting either direction on such a pad
> > therefore programs MODE_DIGITAL_INPUT_OUTPUT rather than the requested
> > direction.
> >
> > That silently breaks both directions. After gpiod_direction_input() the
> > pad keeps driving the line, since the output buffer is never disabled.
> > And after gpiod_direction_output() pmic_gpio_get_direction() still reports
> > GPIO_LINE_DIRECTION_IN, because it cannot tell plain input from
> > input+output, which makes gpiolib consider the line an input while the
> > driver is driving it. On a board where several regulator-fixed nodes
> > share one PMIC GPIO the shared GPIO proxy reads that direction back and
> > rejects every consumer after the first:
> >
> > reg-fixed-voltage regulator-wcn-core-vm-1p35: setup of GPIO (default) failed: -1
> > reg-fixed-voltage regulator-wcn-core-vm-1p35: error -EPERM: can't get GPIO
> >
> > Pack the opposite buffer's PIN_CONFIG_*_ENABLE along with the requested
> > direction so that the resulting MODE_CTL is DIGITAL_INPUT or
> > DIGITAL_OUTPUT, never both. pmic_gpio_config_set() programs the registers
> > once after walking all configs, so this stays a single register write.
> >
> > Pads that are genuinely bidirectional can still be described that way
> > through pinconf, which is the interface that has always been able to
> > express it; the gpiolib direction callbacks now mean what gpiolib says
> > they mean.
> >
> > Fixes: 263447532463 ("pinctrl: qcom: spmi-gpio: implement .get_direction()")
> > Assisted-by: LLM
> > Signed-off-by: Shawn Guo <shengchao.guo@oss.qualcomm.com>
> > ---
> > Changes for v2:
> > - Drop GPIO shared-proxy patch
> > - Update Fixes tag (Thanks Neil!)
> > - Link to v1: https://lore.kernel.org/all/20260915014447.282121-1-shengchao.guo@oss.qualcomm.com/
> >
> > drivers/pinctrl/qcom/pinctrl-spmi-gpio.c | 16 ++++++++++------
> > 1 file changed, 10 insertions(+), 6 deletions(-)
> >
> > diff --git a/drivers/pinctrl/qcom/pinctrl-spmi-gpio.c b/drivers/pinctrl/qcom/pinctrl-spmi-gpio.c
> > index f6dc43e27b38..eb4431591331 100644
> > --- a/drivers/pinctrl/qcom/pinctrl-spmi-gpio.c
> > +++ b/drivers/pinctrl/qcom/pinctrl-spmi-gpio.c
> > @@ -741,22 +741,26 @@ static int pmic_gpio_get_direction(struct gpio_chip *chip, unsigned pin)
> > static int pmic_gpio_direction_input(struct gpio_chip *chip, unsigned pin)
> > {
> > struct pmic_gpio_state *state = gpiochip_get_data(chip);
> > - unsigned long config;
> > + unsigned long configs[2];
> >
> > - config = pinconf_to_config_packed(PIN_CONFIG_INPUT_ENABLE, 1);
> > + configs[0] = pinconf_to_config_packed(PIN_CONFIG_OUTPUT_ENABLE, 0);
> > + configs[1] = pinconf_to_config_packed(PIN_CONFIG_INPUT_ENABLE, 1);
> >
> > - return pmic_gpio_config_set(state->ctrl, pin, &config, 1);
> > + return pmic_gpio_config_set(state->ctrl, pin, configs,
> > + ARRAY_SIZE(configs));
> > }
> >
> > static int pmic_gpio_direction_output(struct gpio_chip *chip,
> > unsigned pin, int val)
> > {
> > struct pmic_gpio_state *state = gpiochip_get_data(chip);
> > - unsigned long config;
> > + unsigned long configs[2];
> >
> > - config = pinconf_to_config_packed(PIN_CONFIG_LEVEL, val);
> > + configs[0] = pinconf_to_config_packed(PIN_CONFIG_INPUT_ENABLE, 0);
>
> Sashiko's comment basically says that for open-drain GPIOs, if we set direction
> to output via GPIOLIB and disable the input buffer, then later call
> gpiod_get_value() on that GPIO, we'll never read what's really on the wire. Can
> we not disable the input buffer for open-drain pins?
Yes, that is the better fix -- thanks, I will do that in v3.
Shawn
prev parent reply other threads:[~2026-09-24 3:18 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-22 6:59 [PATCH v2] pinctrl: qcom: spmi-gpio: make direction changes exclusive Shawn Guo
2026-09-23 9:07 ` Bartosz Golaszewski
2026-09-24 3:18 ` Shawn Guo [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=arSWbexBeEYgBY_x@QCOM-aGQu4IUr3Y \
--to=shengchao.guo@oss.qualcomm.com \
--cc=andersson@kernel.org \
--cc=brgl@kernel.org \
--cc=linusw@kernel.org \
--cc=linux-arm-msm@vger.kernel.org \
--cc=linux-gpio@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=neil.armstrong@linaro.org \
--cc=yu.zhang@oss.qualcomm.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.