[PATCH 06/11] firmware: arm_scmi: report the pin-only and GPIO flags of functions
From: Clément Le Goffic
Date: Fri Oct 30 2026 - 12:01:23 EST
Keep the pin-only and GPIO flags that PINCTRL_ATTRIBUTES returns for a
function, and add a function_flags_get operation to read them.
Signed-off-by: Clément Le Goffic <clegoffic@xxxxxxxxxxxx>
---
drivers/firmware/arm_scmi/pinctrl.c | 43 ++++++++++++++++++++++++++++++++-----
include/linux/scmi_protocol.h | 6 +++++-
2 files changed, 43 insertions(+), 6 deletions(-)
diff --git a/drivers/firmware/arm_scmi/pinctrl.c b/drivers/firmware/arm_scmi/pinctrl.c
index 69645ce73d9d..ba602242754c 100644
--- a/drivers/firmware/arm_scmi/pinctrl.c
+++ b/drivers/firmware/arm_scmi/pinctrl.c
@@ -27,6 +27,8 @@
#define GET_FUNCTIONS_NR(x) le32_get_bits((x), GENMASK(15, 0))
#define EXT_NAME_FLAG(x) le32_get_bits((x), BIT(31))
+#define GPIO_FUNC(x) le32_get_bits((x), BIT(17))
+#define PIN_ONLY_FUNC(x) le32_get_bits((x), BIT(16))
#define NUM_ELEMS(x) le32_get_bits((x), GENMASK(15, 0))
#define REMAINING(x) le32_get_bits((x), GENMASK(31, 16))
@@ -107,6 +109,8 @@ struct scmi_group_info {
struct scmi_function_info {
char name[SCMI_MAX_STR_SIZE];
bool present;
+ bool pin_only;
+ bool gpio;
u32 *groups;
u32 nr_groups;
};
@@ -188,8 +192,8 @@ static int scmi_pinctrl_validate_id(const struct scmi_protocol_handle *ph,
static int scmi_pinctrl_attributes(const struct scmi_protocol_handle *ph,
enum scmi_pinctrl_selector_type type,
- u32 selector, char *name,
- u32 *n_elems)
+ u32 selector, char *name, u32 *n_elems,
+ bool *pin_only, bool *gpio)
{
int ret;
struct scmi_xfer *t;
@@ -219,6 +223,12 @@ static int scmi_pinctrl_attributes(const struct scmi_protocol_handle *ph,
if (n_elems)
*n_elems = NUM_ELEMS(rx->attributes);
+ if (pin_only)
+ *pin_only = PIN_ONLY_FUNC(rx->attributes);
+
+ if (gpio)
+ *gpio = GPIO_FUNC(rx->attributes);
+
strscpy(name, rx->name, SCMI_SHORT_NAME_MAX_SIZE);
ext_name_flag = !!EXT_NAME_FLAG(rx->attributes);
@@ -623,7 +633,7 @@ static int scmi_pinctrl_get_group_info(const struct scmi_protocol_handle *ph,
return 0;
ret = scmi_pinctrl_attributes(ph, GROUP_TYPE, selector, group->name,
- &group->nr_pins);
+ &group->nr_pins, NULL, NULL);
if (ret)
return ret;
@@ -702,7 +712,8 @@ static int scmi_pinctrl_get_function_info(const struct scmi_protocol_handle *ph,
return 0;
ret = scmi_pinctrl_attributes(ph, FUNCTION_TYPE, selector, func->name,
- &func->nr_groups);
+ &func->nr_groups, &func->pin_only,
+ &func->gpio);
if (ret)
return ret;
@@ -765,6 +776,26 @@ scmi_pinctrl_function_groups_get(const struct scmi_protocol_handle *ph,
return 0;
}
+static int
+scmi_pinctrl_function_flags_get(const struct scmi_protocol_handle *ph,
+ u32 selector, bool *pin_only, bool *gpio)
+{
+ struct scmi_pinctrl_info *pi = ph->get_priv(ph);
+ int ret;
+
+ if (!pin_only || !gpio)
+ return -EINVAL;
+
+ ret = scmi_pinctrl_get_function_info(ph, selector);
+ if (ret)
+ return ret;
+
+ *pin_only = pi->functions[selector].pin_only;
+ *gpio = pi->functions[selector].gpio;
+
+ return 0;
+}
+
static int scmi_pinctrl_mux_set(const struct scmi_protocol_handle *ph,
u32 selector, u32 group)
{
@@ -785,7 +816,8 @@ static int scmi_pinctrl_get_pin_info(const struct scmi_protocol_handle *ph,
if (pin->present)
return 0;
- ret = scmi_pinctrl_attributes(ph, PIN_TYPE, selector, pin->name, NULL);
+ ret = scmi_pinctrl_attributes(ph, PIN_TYPE, selector, pin->name, NULL,
+ NULL, NULL);
if (ret)
return ret;
@@ -833,6 +865,7 @@ static const struct scmi_pinctrl_proto_ops pinctrl_proto_ops = {
.name_get = scmi_pinctrl_name_get,
.group_pins_get = scmi_pinctrl_group_pins_get,
.function_groups_get = scmi_pinctrl_function_groups_get,
+ .function_flags_get = scmi_pinctrl_function_flags_get,
.mux_set = scmi_pinctrl_mux_set,
.settings_get_one = scmi_pinctrl_settings_get_one,
.settings_get_all = scmi_pinctrl_settings_get_all,
diff --git a/include/linux/scmi_protocol.h b/include/linux/scmi_protocol.h
index 3f7cc35eb861..072190e89064 100644
--- a/include/linux/scmi_protocol.h
+++ b/include/linux/scmi_protocol.h
@@ -785,7 +785,9 @@ enum scmi_pinctrl_conf_type {
* @name_get: returns name by index of given type
* @group_pins_get: returns the set of pins, assigned to the specified group
* @function_groups_get: returns the set of groups, assigned to the specified
- * function
+ * function, or the set of pins for a pin-only function
+ * @function_flags_get: tells whether the specified function is pin-only and
+ * whether it is a GPIO function
* @mux_set: set muxing function for groups of pins
* @settings_get_one: returns one configuration parameter for pin or group
* specified by config_type
@@ -806,6 +808,8 @@ struct scmi_pinctrl_proto_ops {
int (*function_groups_get)(const struct scmi_protocol_handle *ph,
u32 selector, unsigned int *nr_groups,
const unsigned int **groups);
+ int (*function_flags_get)(const struct scmi_protocol_handle *ph,
+ u32 selector, bool *pin_only, bool *gpio);
int (*mux_set)(const struct scmi_protocol_handle *ph, u32 selector,
u32 group);
int (*settings_get_one)(const struct scmi_protocol_handle *ph,
--
2.56.0