public inbox for linux-arm-kernel@lists.infradead.org
 help / color / mirror / Atom feed
* [RFC 0/7] pinctrl-scmi: Add GPIO support
@ 2025-05-05 11:36 Dan Carpenter
  2025-05-05 11:37 ` [RFC 1/7] firmware: arm_scmi: move boiler plate code into the get info functions Dan Carpenter
                   ` (2 more replies)
  0 siblings, 3 replies; 6+ messages in thread
From: Dan Carpenter @ 2025-05-05 11:36 UTC (permalink / raw)
  To: Linus Walleij
  Cc: arm-scmi, Bartosz Golaszewski, Cristian Marussi, linux-arm-kernel,
	linux-gpio, linux-kernel, Sudeep Holla, Vincent Guittot,
	Khaled Ali Ahmed, Girish Pathak, Peng Fan, Takahiro AKASHI

This patchset adds GPIO support to the SCMI pin control driver.
AKASHI Takahiro did some of that work earlier, but we decided to make
this a part of the pinctrl driver instead of a separate GPIO driver.

I'm not really sure how the device tree stuff wires it all in.  I've
been using a mock driver on SCP with virtio to test it.

Dan Carpenter (7):
  firmware: arm_scmi: move boiler plate code into the get info functions
  firmware: arm_scmi: add is_gpio() function
  pinctrl: introduce pinctrl_gpio_get_config()
  pinctrl-scmi: implement PIN_CONFIG_INPUT_VALUE
  pinctrl: Delete PIN_CONFIG_OUTPUT_IMPEDANCE_OHMS support
  pinctrl-scmi: Add GPIO support
  pinctrl-scmi: remove unused struct member

 drivers/firmware/arm_scmi/pinctrl.c     | 146 +++++++++-------
 drivers/pinctrl/core.c                  |  35 ++++
 drivers/pinctrl/pinctrl-scmi.c          | 213 +++++++++++++++++++++++-
 include/linux/pinctrl/consumer.h        |   9 +
 include/linux/pinctrl/pinconf-generic.h |   3 +
 include/linux/scmi_protocol.h           |   2 +
 6 files changed, 339 insertions(+), 69 deletions(-)

-- 
2.47.2



^ permalink raw reply	[flat|nested] 6+ messages in thread

* [RFC 1/7] firmware: arm_scmi: move boiler plate code into the get info functions
  2025-05-05 11:36 [RFC 0/7] pinctrl-scmi: Add GPIO support Dan Carpenter
@ 2025-05-05 11:37 ` Dan Carpenter
  2025-05-30 12:48   ` Cristian Marussi
  2025-05-05 11:37 ` [RFC 2/7] firmware: arm_scmi: add is_gpio() function Dan Carpenter
  2025-05-07  8:54 ` [RFC 0/7] pinctrl-scmi: Add GPIO support Khaled Ali Ahmed
  2 siblings, 1 reply; 6+ messages in thread
From: Dan Carpenter @ 2025-05-05 11:37 UTC (permalink / raw)
  To: Sudeep Holla; +Cc: Cristian Marussi, arm-scmi, linux-arm-kernel, linux-kernel

This code to check whether the selector is valid and if the item has
already been recorded in the array can be moved to the
scmi_pinctrl_get_function_info() type functions.  That way it's in
one place instead of duplicated in each of the callers.

I removed the check for if "pi->nr_groups == 0" because if that were the
case then "selector >= pi->nr_groups" would already be true.  It already
was not checked for pins so this makes things a bit more uniform.

I also removed the check for if (!pin) since pin is an offset into the
middle of an array and can't be NULL.

Signed-off-by: Dan Carpenter <dan.carpenter@linaro.org>
---
 drivers/firmware/arm_scmi/pinctrl.c | 108 +++++++++++++---------------
 1 file changed, 48 insertions(+), 60 deletions(-)

diff --git a/drivers/firmware/arm_scmi/pinctrl.c b/drivers/firmware/arm_scmi/pinctrl.c
index 3855c98caf06..d18c2d248f04 100644
--- a/drivers/firmware/arm_scmi/pinctrl.c
+++ b/drivers/firmware/arm_scmi/pinctrl.c
@@ -596,11 +596,19 @@ static int scmi_pinctrl_pin_free(const struct scmi_protocol_handle *ph, u32 pin)
 }
 
 static int scmi_pinctrl_get_group_info(const struct scmi_protocol_handle *ph,
-				       u32 selector,
-				       struct scmi_group_info *group)
+				       u32 selector)
 {
+	struct scmi_pinctrl_info *pi = ph->get_priv(ph);
+	struct scmi_group_info *group;
 	int ret;
 
+	if (selector >= pi->nr_groups)
+		return -EINVAL;
+
+	group = &pi->groups[selector];
+	if (group->present)
+		return 0;
+
 	ret = scmi_pinctrl_attributes(ph, GROUP_TYPE, selector, group->name,
 				      &group->nr_pins);
 	if (ret)
@@ -632,21 +640,14 @@ static int scmi_pinctrl_get_group_name(const struct scmi_protocol_handle *ph,
 				       u32 selector, const char **name)
 {
 	struct scmi_pinctrl_info *pi = ph->get_priv(ph);
+	int ret;
 
 	if (!name)
 		return -EINVAL;
 
-	if (selector >= pi->nr_groups || pi->nr_groups == 0)
-		return -EINVAL;
-
-	if (!pi->groups[selector].present) {
-		int ret;
-
-		ret = scmi_pinctrl_get_group_info(ph, selector,
-						  &pi->groups[selector]);
-		if (ret)
-			return ret;
-	}
+	ret = scmi_pinctrl_get_group_info(ph, selector);
+	if (ret)
+		return ret;
 
 	*name = pi->groups[selector].name;
 
@@ -658,21 +659,14 @@ static int scmi_pinctrl_group_pins_get(const struct scmi_protocol_handle *ph,
 				       u32 *nr_pins)
 {
 	struct scmi_pinctrl_info *pi = ph->get_priv(ph);
+	int ret;
 
 	if (!pins || !nr_pins)
 		return -EINVAL;
 
-	if (selector >= pi->nr_groups || pi->nr_groups == 0)
-		return -EINVAL;
-
-	if (!pi->groups[selector].present) {
-		int ret;
-
-		ret = scmi_pinctrl_get_group_info(ph, selector,
-						  &pi->groups[selector]);
-		if (ret)
-			return ret;
-	}
+	ret = scmi_pinctrl_get_group_info(ph, selector);
+	if (ret)
+		return ret;
 
 	*pins = pi->groups[selector].group_pins;
 	*nr_pins = pi->groups[selector].nr_pins;
@@ -681,11 +675,19 @@ static int scmi_pinctrl_group_pins_get(const struct scmi_protocol_handle *ph,
 }
 
 static int scmi_pinctrl_get_function_info(const struct scmi_protocol_handle *ph,
-					  u32 selector,
-					  struct scmi_function_info *func)
+					  u32 selector)
 {
+	struct scmi_pinctrl_info *pi = ph->get_priv(ph);
+	struct scmi_function_info *func;
 	int ret;
 
+	if (selector >= pi->nr_functions)
+		return -EINVAL;
+
+	func = &pi->functions[selector];
+	if (func->present)
+		return 0;
+
 	ret = scmi_pinctrl_attributes(ph, FUNCTION_TYPE, selector, func->name,
 				      &func->nr_groups);
 	if (ret)
@@ -716,21 +718,14 @@ static int scmi_pinctrl_get_function_name(const struct scmi_protocol_handle *ph,
 					  u32 selector, const char **name)
 {
 	struct scmi_pinctrl_info *pi = ph->get_priv(ph);
+	int ret;
 
 	if (!name)
 		return -EINVAL;
 
-	if (selector >= pi->nr_functions || pi->nr_functions == 0)
-		return -EINVAL;
-
-	if (!pi->functions[selector].present) {
-		int ret;
-
-		ret = scmi_pinctrl_get_function_info(ph, selector,
-						     &pi->functions[selector]);
-		if (ret)
-			return ret;
-	}
+	ret = scmi_pinctrl_get_function_info(ph, selector);
+	if (ret)
+		return ret;
 
 	*name = pi->functions[selector].name;
 	return 0;
@@ -742,21 +737,14 @@ scmi_pinctrl_function_groups_get(const struct scmi_protocol_handle *ph,
 				 const u32 **groups)
 {
 	struct scmi_pinctrl_info *pi = ph->get_priv(ph);
+	int ret;
 
 	if (!groups || !nr_groups)
 		return -EINVAL;
 
-	if (selector >= pi->nr_functions || pi->nr_functions == 0)
-		return -EINVAL;
-
-	if (!pi->functions[selector].present) {
-		int ret;
-
-		ret = scmi_pinctrl_get_function_info(ph, selector,
-						     &pi->functions[selector]);
-		if (ret)
-			return ret;
-	}
+	ret = scmi_pinctrl_get_function_info(ph, selector);
+	if (ret)
+		return ret;
 
 	*groups = pi->functions[selector].groups;
 	*nr_groups = pi->functions[selector].nr_groups;
@@ -771,13 +759,19 @@ static int scmi_pinctrl_mux_set(const struct scmi_protocol_handle *ph,
 }
 
 static int scmi_pinctrl_get_pin_info(const struct scmi_protocol_handle *ph,
-				     u32 selector, struct scmi_pin_info *pin)
+				     u32 selector)
 {
+	struct scmi_pinctrl_info *pi = ph->get_priv(ph);
+	struct scmi_pin_info *pin;
 	int ret;
 
-	if (!pin)
+	if (selector >= pi->nr_pins)
 		return -EINVAL;
 
+	pin = &pi->pins[selector];
+	if (pin->present)
+		return 0;
+
 	ret = scmi_pinctrl_attributes(ph, PIN_TYPE, selector, pin->name, NULL);
 	if (ret)
 		return ret;
@@ -790,20 +784,14 @@ static int scmi_pinctrl_get_pin_name(const struct scmi_protocol_handle *ph,
 				     u32 selector, const char **name)
 {
 	struct scmi_pinctrl_info *pi = ph->get_priv(ph);
+	int ret;
 
 	if (!name)
 		return -EINVAL;
 
-	if (selector >= pi->nr_pins)
-		return -EINVAL;
-
-	if (!pi->pins[selector].present) {
-		int ret;
-
-		ret = scmi_pinctrl_get_pin_info(ph, selector, &pi->pins[selector]);
-		if (ret)
-			return ret;
-	}
+	ret = scmi_pinctrl_get_pin_info(ph, selector);
+	if (ret)
+		return ret;
 
 	*name = pi->pins[selector].name;
 
-- 
2.47.2



^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [RFC 2/7] firmware: arm_scmi: add is_gpio() function
  2025-05-05 11:36 [RFC 0/7] pinctrl-scmi: Add GPIO support Dan Carpenter
  2025-05-05 11:37 ` [RFC 1/7] firmware: arm_scmi: move boiler plate code into the get info functions Dan Carpenter
@ 2025-05-05 11:37 ` Dan Carpenter
  2025-05-30 13:09   ` Cristian Marussi
  2025-05-07  8:54 ` [RFC 0/7] pinctrl-scmi: Add GPIO support Khaled Ali Ahmed
  2 siblings, 1 reply; 6+ messages in thread
From: Dan Carpenter @ 2025-05-05 11:37 UTC (permalink / raw)
  To: Sudeep Holla; +Cc: Cristian Marussi, arm-scmi, linux-arm-kernel, linux-kernel

Parse the GPIO response in scmi_pinctrl_attributes(), set the gpio
flag, and create an is_gpio() function pointer so that it can be queried.

In SCMI only functions and pins have a GPIO flag so that's why groups are
not handled here.

Signed-off-by: Dan Carpenter <dan.carpenter@linaro.org>
---
 drivers/firmware/arm_scmi/pinctrl.c | 38 ++++++++++++++++++++++++++---
 include/linux/scmi_protocol.h       |  2 ++
 2 files changed, 36 insertions(+), 4 deletions(-)

diff --git a/drivers/firmware/arm_scmi/pinctrl.c b/drivers/firmware/arm_scmi/pinctrl.c
index d18c2d248f04..f842bf7fe628 100644
--- a/drivers/firmware/arm_scmi/pinctrl.c
+++ b/drivers/firmware/arm_scmi/pinctrl.c
@@ -28,6 +28,7 @@
 
 #define EXT_NAME_FLAG(x)	le32_get_bits((x), BIT(31))
 #define NUM_ELEMS(x)		le32_get_bits((x), GENMASK(15, 0))
+#define GPIO_FUNC(x)		le32_get_bits((x), BIT(17))
 
 #define REMAINING(x)		le32_get_bits((x), GENMASK(31, 16))
 #define RETURNED(x)		le32_get_bits((x), GENMASK(11, 0))
@@ -107,6 +108,7 @@ struct scmi_group_info {
 struct scmi_function_info {
 	char name[SCMI_MAX_STR_SIZE];
 	bool present;
+	bool gpio;
 	u32 *groups;
 	u32 nr_groups;
 };
@@ -114,6 +116,7 @@ struct scmi_function_info {
 struct scmi_pin_info {
 	char name[SCMI_MAX_STR_SIZE];
 	bool present;
+	bool gpio;
 };
 
 struct scmi_pinctrl_info {
@@ -189,7 +192,7 @@ 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 selector, char *name, bool *gpio,
 				   u32 *n_elems)
 {
 	int ret;
@@ -217,6 +220,8 @@ static int scmi_pinctrl_attributes(const struct scmi_protocol_handle *ph,
 
 	ret = ph->xops->do_xfer(ph, t);
 	if (!ret) {
+		if (gpio)
+			*gpio = GPIO_FUNC(rx->attributes);
 		if (n_elems)
 			*n_elems = NUM_ELEMS(rx->attributes);
 
@@ -610,7 +615,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);
+				      NULL, &group->nr_pins);
 	if (ret)
 		return ret;
 
@@ -679,6 +684,7 @@ static int scmi_pinctrl_get_function_info(const struct scmi_protocol_handle *ph,
 {
 	struct scmi_pinctrl_info *pi = ph->get_priv(ph);
 	struct scmi_function_info *func;
+	bool gpio;
 	int ret;
 
 	if (selector >= pi->nr_functions)
@@ -689,7 +695,7 @@ 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);
+				      &gpio, &func->nr_groups);
 	if (ret)
 		return ret;
 
@@ -698,6 +704,7 @@ static int scmi_pinctrl_get_function_info(const struct scmi_protocol_handle *ph,
 		return -ENODATA;
 	}
 
+	func->gpio = gpio;
 	func->groups = kmalloc_array(func->nr_groups, sizeof(*func->groups),
 				     GFP_KERNEL);
 	if (!func->groups)
@@ -763,6 +770,7 @@ static int scmi_pinctrl_get_pin_info(const struct scmi_protocol_handle *ph,
 {
 	struct scmi_pinctrl_info *pi = ph->get_priv(ph);
 	struct scmi_pin_info *pin;
+	bool gpio;
 	int ret;
 
 	if (selector >= pi->nr_pins)
@@ -772,10 +780,12 @@ 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, &gpio,
+				      NULL);
 	if (ret)
 		return ret;
 
+	pin->gpio = gpio;
 	pin->present = true;
 	return 0;
 }
@@ -815,9 +825,29 @@ static int scmi_pinctrl_name_get(const struct scmi_protocol_handle *ph,
 	}
 }
 
+static int scmi_pinctrl_is_gpio(const struct scmi_protocol_handle *ph,
+				u32 selector,
+				enum scmi_pinctrl_selector_type type)
+{
+	struct scmi_pinctrl_info *pi = ph->get_priv(ph);
+	int ret;
+
+	ret = scmi_pinctrl_get_pin_info(ph, selector);
+	if (ret)
+		return ret;
+
+	if (type == PIN_TYPE)
+		return pi->pins[selector].gpio;
+	if (type == FUNCTION_TYPE)
+		return pi->functions[selector].gpio;
+
+	return -EINVAL;
+}
+
 static const struct scmi_pinctrl_proto_ops pinctrl_proto_ops = {
 	.count_get = scmi_pinctrl_count_get,
 	.name_get = scmi_pinctrl_name_get,
+	.is_gpio = scmi_pinctrl_is_gpio,
 	.group_pins_get = scmi_pinctrl_group_pins_get,
 	.function_groups_get = scmi_pinctrl_function_groups_get,
 	.mux_set = scmi_pinctrl_mux_set,
diff --git a/include/linux/scmi_protocol.h b/include/linux/scmi_protocol.h
index 688466a0e816..b4ad32067fc4 100644
--- a/include/linux/scmi_protocol.h
+++ b/include/linux/scmi_protocol.h
@@ -792,6 +792,8 @@ struct scmi_pinctrl_proto_ops {
 	int (*name_get)(const struct scmi_protocol_handle *ph, u32 selector,
 			enum scmi_pinctrl_selector_type type,
 			const char **name);
+	int (*is_gpio)(const struct scmi_protocol_handle *ph, u32 selector,
+		       enum scmi_pinctrl_selector_type type);
 	int (*group_pins_get)(const struct scmi_protocol_handle *ph,
 			      u32 selector, const unsigned int **pins,
 			      unsigned int *nr_pins);
-- 
2.47.2



^ permalink raw reply related	[flat|nested] 6+ messages in thread

* Re: [RFC 0/7] pinctrl-scmi: Add GPIO support
  2025-05-05 11:36 [RFC 0/7] pinctrl-scmi: Add GPIO support Dan Carpenter
  2025-05-05 11:37 ` [RFC 1/7] firmware: arm_scmi: move boiler plate code into the get info functions Dan Carpenter
  2025-05-05 11:37 ` [RFC 2/7] firmware: arm_scmi: add is_gpio() function Dan Carpenter
@ 2025-05-07  8:54 ` Khaled Ali Ahmed
  2 siblings, 0 replies; 6+ messages in thread
From: Khaled Ali Ahmed @ 2025-05-07  8:54 UTC (permalink / raw)
  To: Dan Carpenter, Linus Walleij
  Cc: arm-scmi@vger.kernel.org, Bartosz Golaszewski, Cristian Marussi,
	linux-arm-kernel@lists.infradead.org, linux-gpio@vger.kernel.org,
	linux-kernel@vger.kernel.org, Sudeep Holla, Vincent Guittot,
	Girish Pathak, Peng Fan, Takahiro AKASHI

Good morning Dan,
Regarding the scmi_pinctrl stack design, what we have made in the SW is that the stack can communicate with multiple drivers with only two constraints:
1- Implement the interfacing APIs. which is declared by the object "struct mod_pinctrl_drv_api".
2- Integrate itself with the scmi_pinctrl HAL or backend as you prefer.
Also, we have an example I can discuss if you like.

thanks in advance

________________________________________
From: Dan Carpenter <dan.carpenter@linaro.org>
Sent: Monday, May 5, 2025 12:36 PM
To: Linus Walleij <linus.walleij@linaro.org>
Cc: arm-scmi@vger.kernel.org <arm-scmi@vger.kernel.org>; Bartosz Golaszewski <brgl@bgdev.pl>; Cristian Marussi <Cristian.Marussi@arm.com>; linux-arm-kernel@lists.infradead.org <linux-arm-kernel@lists.infradead.org>; linux-gpio@vger.kernel.org <linux-gpio@vger.kernel.org>; linux-kernel@vger.kernel.org <linux-kernel@vger.kernel.org>; Sudeep Holla <Sudeep.Holla@arm.com>; Vincent Guittot <vincent.guittot@linaro.org>; Khaled Ali Ahmed <Khaled.AliAhmed@arm.com>; Girish Pathak <Girish.Pathak@arm.com>; Peng Fan <peng.fan@nxp.com>; Takahiro AKASHI <akashi.tkhro@gmail.com>
Subject: [RFC 0/7] pinctrl-scmi: Add GPIO support
 
This patchset adds GPIO support to the SCMI pin control driver.
AKASHI Takahiro did some of that work earlier, but we decided to make
this a part of the pinctrl driver instead of a separate GPIO driver.

I'm not really sure how the device tree stuff wires it all in.  I've
been using a mock driver on SCP with virtio to test it.

Dan Carpenter (7):
  firmware: arm_scmi: move boiler plate code into the get info functions
  firmware: arm_scmi: add is_gpio() function
  pinctrl: introduce pinctrl_gpio_get_config()
  pinctrl-scmi: implement PIN_CONFIG_INPUT_VALUE
  pinctrl: Delete PIN_CONFIG_OUTPUT_IMPEDANCE_OHMS support
  pinctrl-scmi: Add GPIO support
  pinctrl-scmi: remove unused struct member

 drivers/firmware/arm_scmi/pinctrl.c     | 146 +++++++++-------
 drivers/pinctrl/core.c                  |  35 ++++
 drivers/pinctrl/pinctrl-scmi.c          | 213 +++++++++++++++++++++++-
 include/linux/pinctrl/consumer.h        |   9 +
 include/linux/pinctrl/pinconf-generic.h |   3 +
 include/linux/scmi_protocol.h           |   2 +
 6 files changed, 339 insertions(+), 69 deletions(-)

--
2.47.2


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [RFC 1/7] firmware: arm_scmi: move boiler plate code into the get info functions
  2025-05-05 11:37 ` [RFC 1/7] firmware: arm_scmi: move boiler plate code into the get info functions Dan Carpenter
@ 2025-05-30 12:48   ` Cristian Marussi
  0 siblings, 0 replies; 6+ messages in thread
From: Cristian Marussi @ 2025-05-30 12:48 UTC (permalink / raw)
  To: Dan Carpenter
  Cc: Sudeep Holla, Cristian Marussi, arm-scmi, linux-arm-kernel,
	linux-kernel

On Mon, May 05, 2025 at 02:37:22PM +0300, Dan Carpenter wrote:
> This code to check whether the selector is valid and if the item has
> already been recorded in the array can be moved to the
> scmi_pinctrl_get_function_info() type functions.  That way it's in
> one place instead of duplicated in each of the callers.

Hi Dan,

thanks for this.

> 
> I removed the check for if "pi->nr_groups == 0" because if that were the
> case then "selector >= pi->nr_groups" would already be true.  It already
> was not checked for pins so this makes things a bit more uniform.
> 
> I also removed the check for if (!pin) since pin is an offset into the
> middle of an array and can't be NULL.
>

A much needed and appreciated cleanup. LGTM.

Reviewed-by: Cristian Marussi <cristian.marussi@arm.com>
 
Thanks,
Cristian


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [RFC 2/7] firmware: arm_scmi: add is_gpio() function
  2025-05-05 11:37 ` [RFC 2/7] firmware: arm_scmi: add is_gpio() function Dan Carpenter
@ 2025-05-30 13:09   ` Cristian Marussi
  0 siblings, 0 replies; 6+ messages in thread
From: Cristian Marussi @ 2025-05-30 13:09 UTC (permalink / raw)
  To: Dan Carpenter
  Cc: Sudeep Holla, Cristian Marussi, arm-scmi, linux-arm-kernel,
	linux-kernel

On Mon, May 05, 2025 at 02:37:36PM +0300, Dan Carpenter wrote:
> Parse the GPIO response in scmi_pinctrl_attributes(), set the gpio
> flag, and create an is_gpio() function pointer so that it can be queried.
> 

Hi,

> In SCMI only functions and pins have a GPIO flag so that's why groups are
> not handled here.
> 
> Signed-off-by: Dan Carpenter <dan.carpenter@linaro.org>
> ---
>  drivers/firmware/arm_scmi/pinctrl.c | 38 ++++++++++++++++++++++++++---
>  include/linux/scmi_protocol.h       |  2 ++
>  2 files changed, 36 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/firmware/arm_scmi/pinctrl.c b/drivers/firmware/arm_scmi/pinctrl.c
> index d18c2d248f04..f842bf7fe628 100644
> --- a/drivers/firmware/arm_scmi/pinctrl.c
> +++ b/drivers/firmware/arm_scmi/pinctrl.c
> @@ -28,6 +28,7 @@
>  
>  #define EXT_NAME_FLAG(x)	le32_get_bits((x), BIT(31))
>  #define NUM_ELEMS(x)		le32_get_bits((x), GENMASK(15, 0))
> +#define GPIO_FUNC(x)		le32_get_bits((x), BIT(17))
>  
>  #define REMAINING(x)		le32_get_bits((x), GENMASK(31, 16))
>  #define RETURNED(x)		le32_get_bits((x), GENMASK(11, 0))
> @@ -107,6 +108,7 @@ struct scmi_group_info {
>  struct scmi_function_info {
>  	char name[SCMI_MAX_STR_SIZE];
>  	bool present;
> +	bool gpio;
>  	u32 *groups;
>  	u32 nr_groups;
>  };
> @@ -114,6 +116,7 @@ struct scmi_function_info {
>  struct scmi_pin_info {
>  	char name[SCMI_MAX_STR_SIZE];
>  	bool present;
> +	bool gpio;
>  };
>  
>  struct scmi_pinctrl_info {
> @@ -189,7 +192,7 @@ 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 selector, char *name, bool *gpio,
>  				   u32 *n_elems)
>  {
>  	int ret;
> @@ -217,6 +220,8 @@ static int scmi_pinctrl_attributes(const struct scmi_protocol_handle *ph,
>  
>  	ret = ph->xops->do_xfer(ph, t);
>  	if (!ret) {
> +		if (gpio)
> +			*gpio = GPIO_FUNC(rx->attributes);
>  		if (n_elems)
>  			*n_elems = NUM_ELEMS(rx->attributes);
>  
> @@ -610,7 +615,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);
> +				      NULL, &group->nr_pins);
>  	if (ret)
>  		return ret;
>  
> @@ -679,6 +684,7 @@ static int scmi_pinctrl_get_function_info(const struct scmi_protocol_handle *ph,
>  {
>  	struct scmi_pinctrl_info *pi = ph->get_priv(ph);
>  	struct scmi_function_info *func;
> +	bool gpio;

...can we just avoid this local var and just...

>  	int ret;
>  
>  	if (selector >= pi->nr_functions)
> @@ -689,7 +695,7 @@ 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);
> +				      &gpio, &func->nr_groups);

				      &func->gpio, &func->nr_groups);

>  	if (ret)
>  		return ret;
>  
> @@ -698,6 +704,7 @@ static int scmi_pinctrl_get_function_info(const struct scmi_protocol_handle *ph,
>  		return -ENODATA;
>  	}
>  
> +	func->gpio = gpio;

...and dropping this...

>  	func->groups = kmalloc_array(func->nr_groups, sizeof(*func->groups),
>  				     GFP_KERNEL);
>  	if (!func->groups)
> @@ -763,6 +770,7 @@ static int scmi_pinctrl_get_pin_info(const struct scmi_protocol_handle *ph,
>  {
>  	struct scmi_pinctrl_info *pi = ph->get_priv(ph);
>  	struct scmi_pin_info *pin;
> +	bool gpio;

... same here...

>  	int ret;
>  
>  	if (selector >= pi->nr_pins)
> @@ -772,10 +780,12 @@ 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, &gpio,
> +				      NULL);

Ditto.

>  	if (ret)
>  		return ret;
>  
> +	pin->gpio = gpio;

Ditto.

>  	pin->present = true;
>  	return 0;
>  }
> @@ -815,9 +825,29 @@ static int scmi_pinctrl_name_get(const struct scmi_protocol_handle *ph,
>  	}
>  }
>  
> +static int scmi_pinctrl_is_gpio(const struct scmi_protocol_handle *ph,
> +				u32 selector,
> +				enum scmi_pinctrl_selector_type type)

being an is_something function could not make it return a bool ?

...but of course loosing the return error code in case of query is_gpio
on a group, and just maybe returning false in that case and a
dev_warn()... (but I have still not seen how this is used by your driver
as of this review...)

> +{
> +	struct scmi_pinctrl_info *pi = ph->get_priv(ph);
> +	int ret;
> +
> +	ret = scmi_pinctrl_get_pin_info(ph, selector);
> +	if (ret)
> +		return ret;
> +
> +	if (type == PIN_TYPE)
> +		return pi->pins[selector].gpio;
> +	if (type == FUNCTION_TYPE)
> +		return pi->functions[selector].gpio;
> +
> +	return -EINVAL;
> +}
> +
>  static const struct scmi_pinctrl_proto_ops pinctrl_proto_ops = {
>  	.count_get = scmi_pinctrl_count_get,
>  	.name_get = scmi_pinctrl_name_get,
> +	.is_gpio = scmi_pinctrl_is_gpio,
>  	.group_pins_get = scmi_pinctrl_group_pins_get,
>  	.function_groups_get = scmi_pinctrl_function_groups_get,
>  	.mux_set = scmi_pinctrl_mux_set,
> diff --git a/include/linux/scmi_protocol.h b/include/linux/scmi_protocol.h
> index 688466a0e816..b4ad32067fc4 100644
> --- a/include/linux/scmi_protocol.h
> +++ b/include/linux/scmi_protocol.h
> @@ -792,6 +792,8 @@ struct scmi_pinctrl_proto_ops {
>  	int (*name_get)(const struct scmi_protocol_handle *ph, u32 selector,
>  			enum scmi_pinctrl_selector_type type,
>  			const char **name);
> +	int (*is_gpio)(const struct scmi_protocol_handle *ph, u32 selector,
> +		       enum scmi_pinctrl_selector_type type);o

Doxygen comment above too please...

>  	int (*group_pins_get)(const struct scmi_protocol_handle *ph,
>  			      u32 selector, const unsigned int **pins,
>  			      unsigned int *nr_pins);
> -- 
> 2.47.2
> 

Thanks,
Cristian



^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2025-05-30 13:11 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-05-05 11:36 [RFC 0/7] pinctrl-scmi: Add GPIO support Dan Carpenter
2025-05-05 11:37 ` [RFC 1/7] firmware: arm_scmi: move boiler plate code into the get info functions Dan Carpenter
2025-05-30 12:48   ` Cristian Marussi
2025-05-05 11:37 ` [RFC 2/7] firmware: arm_scmi: add is_gpio() function Dan Carpenter
2025-05-30 13:09   ` Cristian Marussi
2025-05-07  8:54 ` [RFC 0/7] pinctrl-scmi: Add GPIO support Khaled Ali Ahmed

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox