Re: [PATCH 2/2] pinctrl: qcom: Add qcom,remote-owned pin configuration support
From: Bartosz Golaszewski
Date: Tue Nov 10 2026 - 06:51:44 EST
On Fri, Nov 06, 2026 at 01:29:42PM +0530, Pankaj Patil wrote:
> The eGPIO support added was incomplete since pin ownership is independent
> of the selected mux function: the eGPIO present bit only describes
> whether a pin is capable of being owned remotely, and the enable bit
> selects the owner - 1 sets the owner as APPS and 0 sets the owner as
> remote io. At present it's a mux level decision by setting the function
> as "egpio", APPS releases the ownership to remote io and in process
> cannot use it for any other function.
>
> Add a driver specific pinconf parameter enabling the "qcom,remote-owned"
> dt property support. pinconf-generic falls back to the default value of
> 1 whenever the property carries no value, and an absent property is
> skipped entirely. Since pinconf-generic emits the mux mapping ahead of
> the config mapping, this is applied after msm_pinmux_set_mux() has
> set the pin ownership, giving the intended result for a state that
> specifies both a function and remote-owned.
>
> The hardware programming guide(hpg) explicitly mentions that the egpio
> enable bit can be set independently of whatever the function select bits
> are set to on targets which require shared ownership while the APPS
> continues to use it as normal mux function.
>
> msm_gpio_dbg_show_one() printed "egpio" and returned early whenever the
> enable bit was clear, which was sufficient while that state could only be
> reached by muxing to the egpio function. Ownership is no longer tied to
> the mux, so report it as a suffix on the regular line and keep the
> direction, value, mux, drive strength and bias visible. Pins muxed to the
> egpio function reach the same register state and so print the full line
> too; their mux field reflects the previously selected function.
>
> Fixes: bebc49c1e5f6 ("pinctrl: qcom: Add egpio feature support")
> Signed-off-by: Pankaj Patil <pankaj.patil@xxxxxxxxxxxxxxxx>
> ---
> drivers/pinctrl/qcom/pinctrl-msm.c | 81 ++++++++++++++++++++++++++++++++++----
> 1 file changed, 73 insertions(+), 8 deletions(-)
>
> diff --git a/drivers/pinctrl/qcom/pinctrl-msm.c b/drivers/pinctrl/qcom/pinctrl-msm.c
> index 32aa7b919e24..4d96260f9909 100644
> --- a/drivers/pinctrl/qcom/pinctrl-msm.c
> +++ b/drivers/pinctrl/qcom/pinctrl-msm.c
> @@ -48,6 +48,31 @@ struct msm_pin_state {
> bool saved;
> };
>
> +/*
> + * Driver specific pinconf parameter to hand a pin over to its eGPIO owner
> + * without muxing the TLMM away to the virtual eGPIO function. The eGPIO
> + * present bit only describes whether a pin is capable of being owned
> + * remotely; ownership itself is independent of the selected mux function,
> + * so a pin can keep its normal function selected while being owned by the
> + * remote subsystem.
> + *
> + * The "remote-owned" property is a boolean flag: its mere presence releases
> + * the pin to the remote owner. The default value below is what makes a
> + * valueless property come out as "release", as pinconf-generic falls back to
> + * it whenever the property carries no value.
> + */
> +#define PIN_CONFIG_REMOTE_OWNED (PIN_CONFIG_END + 1)
> +
> +static const struct pinconf_generic_params msm_gpio_bindings[] = {
> + { "qcom,remote-owned", PIN_CONFIG_REMOTE_OWNED, 1 },
> +};
> +
> +#ifdef CONFIG_DEBUG_FS
> +static const struct pin_config_item msm_conf_items[] = {
> + PCONFDUMP(PIN_CONFIG_REMOTE_OWNED, "qcom,remote-owned", NULL, false),
> +};
> +#endif
> +
> /**
> * struct msm_pinctrl - state for a pinctrl-msm device
> * @dev: device handle.
> @@ -328,6 +353,10 @@ static int msm_config_reg(struct msm_pinctrl *pctrl,
> *bit = g->oe_bit;
> *mask = 1;
> break;
> + case PIN_CONFIG_REMOTE_OWNED:
> + *bit = g->egpio_enable;
> + *mask = 1;
> + break;
> default:
> return -ENOTSUPP;
> }
> @@ -424,6 +453,17 @@ static int msm_config_group_get(struct pinctrl_dev *pctldev,
> if (!arg)
> return -EINVAL;
> break;
> + case PIN_CONFIG_REMOTE_OWNED:
> + /* Pin is not eGPIO capable */
> + if (!pctrl->soc->egpio_func || !(val & BIT(g->egpio_present)))
> + return -ENOTSUPP;
> +
> + /* The enable bit is cleared when the remote owns the pin */
> + if (arg)
> + return -EINVAL;
> +
> + arg = 1;
> + break;
> default:
> return -ENOTSUPP;
> }
> @@ -536,6 +576,29 @@ static int msm_config_group_set(struct pinctrl_dev *pctldev,
> case PIN_CONFIG_OUTPUT_ENABLE:
> arg = !!arg;
> break;
> + case PIN_CONFIG_REMOTE_OWNED:
> + if (!pctrl->soc->egpio_func)
> + return -ENOTSUPP;
> +
> + /*
> + * Ownership may only be handed over on eGPIO capable
> + * pins and is released by clearing the enable bit, so
> + * this is applied here rather than through the generic
> + * read-modify-write below.
> + */
> + raw_spin_lock_irqsave(&pctrl->lock, flags);
> + val = msm_readl_ctl(pctrl, g);
> + if (!(val & BIT(g->egpio_present))) {
> + raw_spin_unlock_irqrestore(&pctrl->lock, flags);
> + dev_err(pctrl->dev, "%s is not eGPIO capable\n",
> + g->grp.name);
> + return -ENOTSUPP;
> + }
> +
> + val &= ~BIT(g->egpio_enable);
> + msm_writel_ctl(val, pctrl, g);
> + raw_spin_unlock_irqrestore(&pctrl->lock, flags);
> + continue;
> default:
> dev_err(pctrl->dev, "Unsupported config parameter: %x\n",
> param);
Sashiko didn't spot it but eGPIO functions are now defined as
MSM_GPIO_PIN_FUNCTION() so pins configured as eGPIO can be used via GPIOLIB.
When you call:
gpiod_get()
msm_pinmux_request_gpio()
msm_pinmux_set_mux()
You'll end up clamining the pin again by setting the egpio_enable bit
unconditionally.
Bart