gpio: msm: fix get_function return for special pins

The get_function callback wrongly returns 0 for special pins,
return the appropriate pin function by probing into the special
pins data fields to find if the pin is gpio capable.

Fixes: f9bb539460 ("gpio: msm: add support for special pins")
Signed-off-by: Neil Armstrong <neil.armstrong@linaro.org>
Link: https://lore.kernel.org/r/20250401-topic-sm8x50-msm-gpio-special-fixes-v1-1-a1148a02bb16@linaro.org
Signed-off-by: Caleb Connolly <caleb.connolly@linaro.org>
This commit is contained in:
Neil Armstrong
2025-04-01 09:45:19 +02:00
committed by Caleb Connolly
parent 45acd9d2d4
commit 0708bdd34d

View File

@@ -192,13 +192,41 @@ static int msm_gpio_get_value(struct udevice *dev, unsigned int gpio)
return !!(readl(priv->base + GPIO_IN_OUT_REG(dev, gpio)) >> GPIO_IN);
}
static int msm_gpio_get_function_special(struct msm_gpio_bank *priv,
unsigned int gpio)
{
unsigned int offset = gpio - priv->pin_data->special_pins_start;
const struct msm_special_pin_data *data;
if (!priv->pin_data->special_pins_data)
return GPIOF_UNKNOWN;
data = &priv->pin_data->special_pins_data[offset];
/* No I/O fields, cannot control/read the I/O value */
if (!data->io_reg || (data->out_bit >= 31 && data->in_bit >= 31))
return GPIOF_FUNC;
/* No Output-Enable register, cannot control I/O direction */
if (!data->ctl_reg || data->oe_bit >= 31) {
if (data->out_bit >= 31)
return GPIOF_INPUT;
else
return GPIOF_OUTPUT;
}
if (readl(priv->base + data->ctl_reg) & BIT(data->oe_bit))
return GPIOF_OUTPUT;
return GPIOF_INPUT;
}
static int msm_gpio_get_function(struct udevice *dev, unsigned int gpio)
{
struct msm_gpio_bank *priv = dev_get_priv(dev);
/* Always NOP for special pins, assume they're in the correct state */
if (qcom_is_special_pin(priv->pin_data, gpio))
return 0;
return msm_gpio_get_function_special(priv, gpio);
if (readl(priv->base + GPIO_CONFIG_REG(dev, gpio)) & GPIO_OE_ENABLE)
return GPIOF_OUTPUT;