linux-arm-kernel.lists.infradead.org archive mirror
 help / color / mirror / Atom feed
From: Cristian Marussi <cristian.marussi@arm.com>
To: "Peng Fan (OSS)" <peng.fan@oss.nxp.com>
Cc: Sudeep Holla <sudeep.holla@arm.com>,
	Rob Herring <robh@kernel.org>,
	Krzysztof Kozlowski <krzysztof.kozlowski+dt@linaro.org>,
	Conor Dooley <conor+dt@kernel.org>,
	Linus Walleij <linus.walleij@linaro.org>,
	Dan Carpenter <dan.carpenter@linaro.org>,
	linux-arm-kernel@lists.infradead.org,
	linux-kernel@vger.kernel.org, devicetree@vger.kernel.org,
	linux-gpio@vger.kernel.org, Peng Fan <peng.fan@nxp.com>,
	Oleksii Moisieiev <oleksii_moisieiev@epam.com>
Subject: Re: [PATCH v7 3/4] firmware: arm_scmi: Add SCMI v3.2 pincontrol protocol basic support
Date: Tue, 2 Apr 2024 11:29:02 +0100	[thread overview]
Message-ID: <Zgvd7npz1jdJSu-b@pluto> (raw)
In-Reply-To: <20240402-pinctrl-scmi-v7-3-3ea519d12cf7@nxp.com>

On Tue, Apr 02, 2024 at 10:22:23AM +0800, Peng Fan (OSS) wrote:
> From: Peng Fan <peng.fan@nxp.com>
> 
> Add basic implementation of the SCMI v3.2 pincontrol protocol.
> 

Hi,


> Co-developed-by: Oleksii Moisieiev <oleksii_moisieiev@epam.com>
> Signed-off-by: Oleksii Moisieiev <oleksii_moisieiev@epam.com>
> Signed-off-by: Peng Fan <peng.fan@nxp.com>
> ---

[snip]


> +struct scmi_settings_get_ipriv {
> +	u32 selector;
> +	enum scmi_pinctrl_selector_type type;
> +	bool get_all;
> +	enum scmi_pinctrl_conf_type *config_types;
> +	u32 *config_values;
> +};
> +
> +static void
> +iter_pinctrl_settings_get_prepare_message(void *message, u32 desc_index,
> +					  const void *priv)
> +{
> +	struct scmi_msg_settings_get *msg = message;
> +	const struct scmi_settings_get_ipriv *p = priv;
> +	u32 attributes;
> +
> +	attributes = FIELD_PREP(SELECTOR_MASK, p->type);
> +
> +	if (p->get_all) {
> +		attributes |= FIELD_PREP(CONFIG_FLAG_MASK, 1) |
> +			FIELD_PREP(SKIP_CONFIGS_MASK, desc_index);
> +	} else {
> +		attributes |= FIELD_PREP(CONFIG_TYPE_MASK, p->config_types[0]);
> +	}
> +
> +	msg->attributes = cpu_to_le32(attributes);
> +	msg->identifier = cpu_to_le32(p->selector);
> +}
> +
> +static int
> +iter_pinctrl_settings_get_update_state(struct scmi_iterator_state *st,
> +				       const void *response, void *priv)
> +{
> +	const struct scmi_resp_settings_get *r = response;
> +	struct scmi_settings_get_ipriv *p = priv;
> +
> +	if (p->get_all) {
> +		st->num_returned = le32_get_bits(r->num_configs, GENMASK(7, 0));
> +		st->num_remaining = le32_get_bits(r->num_configs, GENMASK(31, 24));
> +	} else {
> +		st->num_returned = 1;
> +		st->num_remaining = 0;
> +	}
> +
> +	return 0;
> +}
> +
> +static int
> +iter_pinctrl_settings_get_process_response(const struct scmi_protocol_handle *ph,
> +					   const void *response,
> +					   struct scmi_iterator_state *st,
> +					   void *priv)
> +{
> +	const struct scmi_resp_settings_get *r = response;
> +	struct scmi_settings_get_ipriv *p = priv;
> +	u32 type = le32_get_bits(r->configs[st->loop_idx * 2], GENMASK(7, 0));
> +	u32 val = le32_to_cpu(r->configs[st->loop_idx * 2 + 1]);
> +
> +	if (p->get_all) {
> +		p->config_types[st->desc_index + st->loop_idx] = type;
> +	} else {
> +		if (p->config_types[0] != type)
> +			return -EINVAL;
> +	}
> +
> +	p->config_values[st->desc_index + st->loop_idx] = val;
> +
> +	return 0;
> +}
> +
> +static int
> +scmi_pinctrl_settings_get(const struct scmi_protocol_handle *ph, u32 selector,
> +			  enum scmi_pinctrl_selector_type type,
> +			  enum scmi_pinctrl_conf_type config_type,
> +			  u32 *config_value, bool get_all)
> +{
> +	int ret;
> +	void *iter;
> +	struct scmi_iterator_ops ops = {
> +		.prepare_message = iter_pinctrl_settings_get_prepare_message,
> +		.update_state = iter_pinctrl_settings_get_update_state,
> +		.process_response = iter_pinctrl_settings_get_process_response,
> +	};
> +	struct scmi_settings_get_ipriv ipriv = {
> +		.selector = selector,
> +		.type = type,
> +		.get_all = get_all,
> +		.config_types = &config_type,
> +		.config_values = config_value,
> +	};
> +
> +	if (!config_value || type == FUNCTION_TYPE)
> +		return -EINVAL;
> +
> +	ret = scmi_pinctrl_validate_id(ph, selector, type);
> +	if (ret)
> +		return ret;
> +
> +	iter = ph->hops->iter_response_init(ph, &ops, SCMI_PIN_OEM_END,
> +					    PINCTRL_SETTINGS_GET,
> +					    sizeof(struct scmi_msg_settings_get),
> +					    &ipriv);
> +	if (IS_ERR(iter))
> +		return PTR_ERR(iter);
> +
> +	return ph->hops->iter_response_run(iter);
> +}
> +
> +static int scmi_pinctrl_settings_get_one(const struct scmi_protocol_handle *ph,
> +					 u32 selector,
> +					 enum scmi_pinctrl_selector_type type,
> +					 enum scmi_pinctrl_conf_type config_type,
> +					 u32 *config_value)
> +{
> +	return scmi_pinctrl_settings_get(ph, selector, type, config_type,
> +					 config_value, false);
> +}
> +
> +static int scmi_pinctrl_settings_get_all(const struct scmi_protocol_handle *ph,
> +					 u32 selector,
> +					 enum scmi_pinctrl_selector_type type,
> +					 enum scmi_pinctrl_conf_type config_type,
> +					 u32 *config_value)
> +{
> +	return scmi_pinctrl_settings_get(ph, selector, type, config_type,
> +					 config_value, true);
> +}
> +

If you generalize the scmi_pinctrl_settings_get() and reintroduce a
.settings_get_all() ops (even though unused by pinctrl driver, I am fine
with this..), you should take care to pass as an input parameter NOT only
the array of config_values BUT also an array of config_types since you could
get back up to 256 OEM types: for this reason you will need also to pass to
scmi_pinctrl_settings_get() an input param that specifies the sizes of the
2 array input params (in order to avoid oveflows) AND use that same inout
param also as an output param to report at the end how many OEM types were
effectively found and returned....

IOW, I did this on top of your V7 to make the settings_get_all work:

---8<---
diff --git a/drivers/firmware/arm_scmi/pinctrl.c b/drivers/firmware/arm_scmi/pinctrl.c
index b75af1dd75fa..f4937af66c4d 100644
--- a/drivers/firmware/arm_scmi/pinctrl.c
+++ b/drivers/firmware/arm_scmi/pinctrl.c
@@ -317,6 +317,7 @@ struct scmi_settings_get_ipriv {
 	u32 selector;
 	enum scmi_pinctrl_selector_type type;
 	bool get_all;
+	unsigned int *nr_configs;
 	enum scmi_pinctrl_conf_type *config_types;
 	u32 *config_values;
 };
@@ -379,6 +380,7 @@ iter_pinctrl_settings_get_process_response(const struct scmi_protocol_handle *ph
 	}
 
 	p->config_values[st->desc_index + st->loop_idx] = val;
+	++*p->nr_configs;
 
 	return 0;
 }
@@ -386,11 +388,13 @@ iter_pinctrl_settings_get_process_response(const struct scmi_protocol_handle *ph
 static int
 scmi_pinctrl_settings_get(const struct scmi_protocol_handle *ph, u32 selector,
 			  enum scmi_pinctrl_selector_type type,
-			  enum scmi_pinctrl_conf_type config_type,
-			  u32 *config_value, bool get_all)
+			  unsigned int *nr_configs,
+			  enum scmi_pinctrl_conf_type *config_types,
+			  u32 *config_values)
 {
 	int ret;
 	void *iter;
+	unsigned int max_configs = *nr_configs;
 	struct scmi_iterator_ops ops = {
 		.prepare_message = iter_pinctrl_settings_get_prepare_message,
 		.update_state = iter_pinctrl_settings_get_update_state,
@@ -399,19 +403,22 @@ scmi_pinctrl_settings_get(const struct scmi_protocol_handle *ph, u32 selector,
 	struct scmi_settings_get_ipriv ipriv = {
 		.selector = selector,
 		.type = type,
-		.get_all = get_all,
-		.config_types = &config_type,
-		.config_values = config_value,
+		.get_all = (max_configs > 1),
+		.nr_configs = nr_configs,
+		.config_types = config_types,
+		.config_values = config_values,
 	};
 
-	if (!config_value || type == FUNCTION_TYPE)
+	if (!config_types || !config_values || type == FUNCTION_TYPE)
 		return -EINVAL;
 
 	ret = scmi_pinctrl_validate_id(ph, selector, type);
 	if (ret)
 		return ret;
 
-	iter = ph->hops->iter_response_init(ph, &ops, SCMI_PIN_OEM_END,
+	/* Prepare to count returned configs */
+	*nr_configs = 0;
+	iter = ph->hops->iter_response_init(ph, &ops, max_configs,
 					    PINCTRL_SETTINGS_GET,
 					    sizeof(struct scmi_msg_settings_get),
 					    &ipriv);
@@ -427,18 +434,24 @@ static int scmi_pinctrl_settings_get_one(const struct scmi_protocol_handle *ph,
 					 enum scmi_pinctrl_conf_type config_type,
 					 u32 *config_value)
 {
-	return scmi_pinctrl_settings_get(ph, selector, type, config_type,
-					 config_value, false);
+	unsigned int nr_configs = 1;
+
+	return scmi_pinctrl_settings_get(ph, selector, type, &nr_configs,
+					 &config_type, config_value);
 }
 
 static int scmi_pinctrl_settings_get_all(const struct scmi_protocol_handle *ph,
 					 u32 selector,
 					 enum scmi_pinctrl_selector_type type,
-					 enum scmi_pinctrl_conf_type config_type,
-					 u32 *config_value)
+					 unsigned int *nr_configs,
+					 enum scmi_pinctrl_conf_type *config_types,
+					 u32 *config_values)
 {
-	return scmi_pinctrl_settings_get(ph, selector, type, config_type,
-					 config_value, true);
+	if (!nr_configs || *nr_configs == 0)
+		return -EINVAL;
+
+	return scmi_pinctrl_settings_get(ph, selector, type, nr_configs,
+					 config_types, config_values);
 }
 
 static int
diff --git a/include/linux/scmi_protocol.h b/include/linux/scmi_protocol.h
index abaf6122ea37..7915792efd81 100644
--- a/include/linux/scmi_protocol.h
+++ b/include/linux/scmi_protocol.h
@@ -882,8 +882,9 @@ struct scmi_pinctrl_proto_ops {
 	int (*settings_get_all)(const struct scmi_protocol_handle *ph,
 				u32 selector,
 				enum scmi_pinctrl_selector_type type,
-				enum scmi_pinctrl_conf_type config_type,
-				u32 *config_value);
+				unsigned int *nr_configs,
+				enum scmi_pinctrl_conf_type *config_types,
+				u32 *config_values);
 	int (*settings_conf)(const struct scmi_protocol_handle *ph,
 			     u32 selector, enum scmi_pinctrl_selector_type type,
 			     unsigned int nr_configs,
--->8-----

Please check if this addition sounds good to you and integrate into v8
eventually...

Thanks,
Cristian

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

  reply	other threads:[~2024-04-02 10:29 UTC|newest]

Thread overview: 15+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-04-02  2:22 [PATCH v7 0/4] firmware: arm_scmi: Add SCMI v3.2 pincontrol protocol basic support Peng Fan (OSS)
2024-04-02  2:22 ` [PATCH v7 1/4] firmware: arm_scmi: introduce helper get_max_msg_size Peng Fan (OSS)
2024-04-02  2:22 ` [PATCH v7 2/4] dt-bindings: firmware: arm,scmi: support pinctrl protocol Peng Fan (OSS)
2024-04-02  2:22 ` [PATCH v7 3/4] firmware: arm_scmi: Add SCMI v3.2 pincontrol protocol basic support Peng Fan (OSS)
2024-04-02 10:29   ` Cristian Marussi [this message]
2024-04-02 14:04     ` Peng Fan
2024-04-02 13:14   ` Andy Shevchenko
2024-04-02 13:27     ` Peng Fan
2024-04-02 14:05       ` Andy Shevchenko
2024-04-02  2:22 ` [PATCH v7 4/4] pinctrl: Implementation of the generic scmi-pinctrl driver Peng Fan (OSS)
2024-04-02 13:22   ` Andy Shevchenko
2024-04-02 13:59     ` Peng Fan
2024-04-02 14:09       ` Andy Shevchenko
2024-04-02 14:09     ` Dan Carpenter
2024-04-02 16:40       ` Cristian Marussi

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=Zgvd7npz1jdJSu-b@pluto \
    --to=cristian.marussi@arm.com \
    --cc=conor+dt@kernel.org \
    --cc=dan.carpenter@linaro.org \
    --cc=devicetree@vger.kernel.org \
    --cc=krzysztof.kozlowski+dt@linaro.org \
    --cc=linus.walleij@linaro.org \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-gpio@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=oleksii_moisieiev@epam.com \
    --cc=peng.fan@nxp.com \
    --cc=peng.fan@oss.nxp.com \
    --cc=robh@kernel.org \
    --cc=sudeep.holla@arm.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).