[PATCH 11/11] pinctrl: scmi: select the GPIO function on GPIO requests
From: Clément Le Goffic
Date: Fri Oct 30 2026 - 12:04:42 EST
On a GPIO request, select the GPIO function of the pin, on the pin for a
pin-only function or on its single-pin group. Without a GPIO function the
mux is left as it is.
Signed-off-by: Clément Le Goffic <clegoffic@xxxxxxxxxxxx>
---
drivers/pinctrl/pinctrl-scmi.c | 64 ++++++++++++++++++++++++++++++++++++++++++
1 file changed, 64 insertions(+)
diff --git a/drivers/pinctrl/pinctrl-scmi.c b/drivers/pinctrl/pinctrl-scmi.c
index 6f44e8c0fee6..ba649304638e 100644
--- a/drivers/pinctrl/pinctrl-scmi.c
+++ b/drivers/pinctrl/pinctrl-scmi.c
@@ -74,6 +74,69 @@ static int pinctrl_scmi_free(struct pinctrl_dev *pctldev, unsigned int offset)
return pinctrl_ops->pin_free(pmx->ph, offset);
}
+static int pinctrl_scmi_gpio_mux_set(struct scmi_pinctrl *pmx, unsigned int pin)
+{
+ const unsigned int *elems, *pins;
+ unsigned int nr_elems, nr_pins, i;
+ bool pin_only, gpio;
+ int nr_functions, func, ret;
+
+ nr_functions = pinctrl_ops->count_get(pmx->ph, FUNCTION_TYPE);
+ for (func = 0; func < nr_functions; func++) {
+ ret = pinctrl_ops->function_flags_get(pmx->ph, func, &pin_only,
+ &gpio);
+ if (ret)
+ return ret;
+
+ if (!gpio)
+ continue;
+
+ ret = pinctrl_ops->function_groups_get(pmx->ph, func, &nr_elems,
+ &elems);
+ if (ret)
+ return ret;
+
+ for (i = 0; i < nr_elems; i++) {
+ if (pin_only) {
+ if (elems[i] != pin)
+ continue;
+
+ return pinctrl_ops->pin_mux_set(pmx->ph, func,
+ pin);
+ }
+
+ ret = pinctrl_ops->group_pins_get(pmx->ph, elems[i],
+ &pins, &nr_pins);
+ if (ret)
+ return ret;
+
+ if (nr_pins == 1 && pins[0] == pin)
+ return pinctrl_ops->mux_set(pmx->ph, func,
+ elems[i]);
+ }
+ }
+
+ return 0;
+}
+
+static int pinctrl_scmi_gpio_request_enable(struct pinctrl_dev *pctldev,
+ struct pinctrl_gpio_range *range,
+ unsigned int offset)
+{
+ struct scmi_pinctrl *pmx = pinctrl_dev_get_drvdata(pctldev);
+ int ret;
+
+ ret = pinctrl_ops->pin_request(pmx->ph, offset);
+ if (ret)
+ return ret;
+
+ ret = pinctrl_scmi_gpio_mux_set(pmx, offset);
+ if (ret)
+ pinctrl_ops->pin_free(pmx->ph, offset);
+
+ return ret;
+}
+
static const struct pinmux_ops pinctrl_scmi_pinmux_ops = {
.request = pinctrl_scmi_request,
.free = pinctrl_scmi_free,
@@ -82,6 +145,7 @@ static const struct pinmux_ops pinctrl_scmi_pinmux_ops = {
.get_function_groups = pinmux_generic_get_function_groups,
.function_is_gpio = pinmux_generic_function_is_gpio,
.set_mux = pinctrl_scmi_func_set_mux,
+ .gpio_request_enable = pinctrl_scmi_gpio_request_enable,
};
static int pinctrl_scmi_map_pinconf_type(enum pin_config_param param,
--
2.56.0