All of lore.kernel.org
 help / color / mirror / Atom feed
From: Matthew Bystrin <dev.mbstr@gmail.com>
To: arm-scmi@vger.kernel.org, Sudeep Holla <sudeep.holla@arm.com>
Cc: linux-kernel@vger.kernel.org,
	linux-arm-kernel@lists.infradead.org,
	Cristian Marussi <cristian.marussi@arm.com>,
	Philipp Zabel <p.zabel@pengutronix.de>,
	Peng Fan <peng.fan@nxp.com>
Subject: [PATCH] firmware: arm_scmi: add timeout in do_xfer_with_response()
Date: Wed,  2 Apr 2025 13:42:54 +0300	[thread overview]
Message-ID: <20250402104254.149998-1-dev.mbstr@gmail.com> (raw)

Add timeout argument to do_xfer_with_response() with subsequent changes
in corresponding drivers. To maintain backward compatibility use
previous hardcoded timeout value.

According to SCMI specification [1] there is no defined timeout for
delayed messages in the interface. While hardcoded 2 seconds timeout
might be good enough for existing protocol drivers, moving it to the
function argument may be useful for vendor-specific protocols with
different timing needs.

Link: https://developer.arm.com/Architectures/System%20Control%20and%20Management%20Interface
Signed-off-by: Matthew Bystrin <dev.mbstr@gmail.com>
---
 drivers/firmware/arm_scmi/clock.c     | 2 +-
 drivers/firmware/arm_scmi/common.h    | 1 -
 drivers/firmware/arm_scmi/driver.c    | 6 ++++--
 drivers/firmware/arm_scmi/powercap.c  | 2 +-
 drivers/firmware/arm_scmi/protocols.h | 3 ++-
 drivers/firmware/arm_scmi/reset.c     | 2 +-
 drivers/firmware/arm_scmi/sensors.c   | 4 ++--
 drivers/firmware/arm_scmi/voltage.c   | 2 +-
 include/linux/scmi_protocol.h         | 1 +
 9 files changed, 13 insertions(+), 10 deletions(-)

diff --git a/drivers/firmware/arm_scmi/clock.c b/drivers/firmware/arm_scmi/clock.c
index 2ed2279388f0..4b5cd73384c3 100644
--- a/drivers/firmware/arm_scmi/clock.c
+++ b/drivers/firmware/arm_scmi/clock.c
@@ -596,7 +596,7 @@ static int scmi_clock_rate_set(const struct scmi_protocol_handle *ph,
 	cfg->value_high = cpu_to_le32(rate >> 32);
 
 	if (flags & CLOCK_SET_ASYNC) {
-		ret = ph->xops->do_xfer_with_response(ph, t);
+		ret = ph->xops->do_xfer_with_response(ph, t, SCMI_DEFAULT_TIMEOUT);
 		if (!ret) {
 			struct scmi_msg_resp_set_rate_complete *resp;
 
diff --git a/drivers/firmware/arm_scmi/common.h b/drivers/firmware/arm_scmi/common.h
index 10ea7962323e..34527366c909 100644
--- a/drivers/firmware/arm_scmi/common.h
+++ b/drivers/firmware/arm_scmi/common.h
@@ -29,7 +29,6 @@
 
 #define SCMI_MAX_CHANNELS		256
 
-#define SCMI_MAX_RESPONSE_TIMEOUT	(2 * MSEC_PER_SEC)
 
 #define SCMI_SHMEM_MAX_PAYLOAD_SIZE	104
 
diff --git a/drivers/firmware/arm_scmi/driver.c b/drivers/firmware/arm_scmi/driver.c
index 1c75a4c9c371..51c6634d5505 100644
--- a/drivers/firmware/arm_scmi/driver.c
+++ b/drivers/firmware/arm_scmi/driver.c
@@ -1490,6 +1490,7 @@ static void reset_rx_to_maxsz(const struct scmi_protocol_handle *ph,
  *
  * @ph: Pointer to SCMI protocol handle
  * @xfer: Transfer to initiate and wait for response
+ * @timeout_ms: Delayed response wait timeout, if unsure use SCMI_DEFAULT_TIMEOUT
  *
  * Using asynchronous commands in atomic/polling mode should be avoided since
  * it could cause long busy-waiting here, so ignore polling for the delayed
@@ -1509,9 +1510,10 @@ static void reset_rx_to_maxsz(const struct scmi_protocol_handle *ph,
  *	return corresponding error, else if all goes well, return 0.
  */
 static int do_xfer_with_response(const struct scmi_protocol_handle *ph,
-				 struct scmi_xfer *xfer)
+				 struct scmi_xfer *xfer, unsigned long timeout_ms)
 {
-	int ret, timeout = msecs_to_jiffies(SCMI_MAX_RESPONSE_TIMEOUT);
+	int ret;
+	unsigned long timeout = msecs_to_jiffies(timeout_ms);
 	DECLARE_COMPLETION_ONSTACK(async_response);
 
 	xfer->async_done = &async_response;
diff --git a/drivers/firmware/arm_scmi/powercap.c b/drivers/firmware/arm_scmi/powercap.c
index 1fa79bba492e..82565dacd301 100644
--- a/drivers/firmware/arm_scmi/powercap.c
+++ b/drivers/firmware/arm_scmi/powercap.c
@@ -386,7 +386,7 @@ static int scmi_powercap_xfer_cap_set(const struct scmi_protocol_handle *ph,
 	if (!pc->async_powercap_cap_set || ignore_dresp) {
 		ret = ph->xops->do_xfer(ph, t);
 	} else {
-		ret = ph->xops->do_xfer_with_response(ph, t);
+		ret = ph->xops->do_xfer_with_response(ph, t, SCMI_DEFAULT_TIMEOUT);
 		if (!ret) {
 			struct scmi_msg_resp_powercap_cap_set_complete *resp;
 
diff --git a/drivers/firmware/arm_scmi/protocols.h b/drivers/firmware/arm_scmi/protocols.h
index aaee57cdcd55..b1e3cf3601fe 100644
--- a/drivers/firmware/arm_scmi/protocols.h
+++ b/drivers/firmware/arm_scmi/protocols.h
@@ -307,7 +307,8 @@ struct scmi_xfer_ops {
 	int (*do_xfer)(const struct scmi_protocol_handle *ph,
 		       struct scmi_xfer *xfer);
 	int (*do_xfer_with_response)(const struct scmi_protocol_handle *ph,
-				     struct scmi_xfer *xfer);
+				     struct scmi_xfer *xfer,
+				     unsigned long timeout_ms);
 	void (*xfer_put)(const struct scmi_protocol_handle *ph,
 			 struct scmi_xfer *xfer);
 };
diff --git a/drivers/firmware/arm_scmi/reset.c b/drivers/firmware/arm_scmi/reset.c
index 0aa82b96f41b..a458b1c16c51 100644
--- a/drivers/firmware/arm_scmi/reset.c
+++ b/drivers/firmware/arm_scmi/reset.c
@@ -198,7 +198,7 @@ static int scmi_domain_reset(const struct scmi_protocol_handle *ph, u32 domain,
 	dom->reset_state = cpu_to_le32(state);
 
 	if (flags & ASYNCHRONOUS_RESET)
-		ret = ph->xops->do_xfer_with_response(ph, t);
+		ret = ph->xops->do_xfer_with_response(ph, t, SCMI_DEFAULT_TIMEOUT);
 	else
 		ret = ph->xops->do_xfer(ph, t);
 
diff --git a/drivers/firmware/arm_scmi/sensors.c b/drivers/firmware/arm_scmi/sensors.c
index 791efd0f82d7..9a07399237f5 100644
--- a/drivers/firmware/arm_scmi/sensors.c
+++ b/drivers/firmware/arm_scmi/sensors.c
@@ -871,7 +871,7 @@ static int scmi_sensor_reading_get(const struct scmi_protocol_handle *ph,
 	s = si->sensors + sensor_id;
 	if (s->async) {
 		sensor->flags = cpu_to_le32(SENSOR_READ_ASYNC);
-		ret = ph->xops->do_xfer_with_response(ph, t);
+		ret = ph->xops->do_xfer_with_response(ph, t, SCMI_DEFAULT_TIMEOUT);
 		if (!ret) {
 			struct scmi_resp_sensor_reading_complete *resp;
 
@@ -943,7 +943,7 @@ scmi_sensor_reading_get_timestamped(const struct scmi_protocol_handle *ph,
 	sensor->id = cpu_to_le32(sensor_id);
 	if (s->async) {
 		sensor->flags = cpu_to_le32(SENSOR_READ_ASYNC);
-		ret = ph->xops->do_xfer_with_response(ph, t);
+		ret = ph->xops->do_xfer_with_response(ph, t, SCMI_DEFAULT_TIMEOUT);
 		if (!ret) {
 			int i;
 			struct scmi_resp_sensor_reading_complete_v3 *resp;
diff --git a/drivers/firmware/arm_scmi/voltage.c b/drivers/firmware/arm_scmi/voltage.c
index fda6a1573609..26b1f034256b 100644
--- a/drivers/firmware/arm_scmi/voltage.c
+++ b/drivers/firmware/arm_scmi/voltage.c
@@ -348,7 +348,7 @@ static int scmi_voltage_level_set(const struct scmi_protocol_handle *ph,
 		ret = ph->xops->do_xfer(ph, t);
 	} else {
 		cmd->flags = cpu_to_le32(0x1);
-		ret = ph->xops->do_xfer_with_response(ph, t);
+		ret = ph->xops->do_xfer_with_response(ph, t, SCMI_DEFAULT_TIMEOUT);
 		if (!ret) {
 			struct scmi_resp_voltage_level_set_complete *resp;
 
diff --git a/include/linux/scmi_protocol.h b/include/linux/scmi_protocol.h
index 688466a0e816..2426daae8a87 100644
--- a/include/linux/scmi_protocol.h
+++ b/include/linux/scmi_protocol.h
@@ -16,6 +16,7 @@
 #define SCMI_MAX_STR_SIZE		64
 #define SCMI_SHORT_NAME_MAX_SIZE	16
 #define SCMI_MAX_NUM_RATES		16
+#define SCMI_DEFAULT_TIMEOUT		(2 * MSEC_PER_SEC)
 
 /**
  * struct scmi_revision_info - version information structure
-- 
2.47.2


             reply	other threads:[~2025-04-02 10:42 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-04-02 10:42 Matthew Bystrin [this message]
2025-04-02 10:59 ` [PATCH] firmware: arm_scmi: add timeout in do_xfer_with_response() Sudeep Holla
2025-04-02 16:05   ` Cristian Marussi
2025-04-03  8:59     ` Sudeep Holla
2025-04-03 19:50     ` Matthew Bystrin
2025-04-08 20:22       ` Matthew Bystrin
2025-04-09 10:52         ` Cristian Marussi
2025-04-09 10:54           ` Cristian Marussi
2025-04-09  0:57       ` Peng Fan
2025-04-09 11:12       ` Sudeep Holla
2025-04-12 10:39         ` Matthew Bystrin
2025-04-14  8:38           ` Cristian Marussi
2025-04-21  5:37             ` Matthew Bystrin

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=20250402104254.149998-1-dev.mbstr@gmail.com \
    --to=dev.mbstr@gmail.com \
    --cc=arm-scmi@vger.kernel.org \
    --cc=cristian.marussi@arm.com \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=p.zabel@pengutronix.de \
    --cc=peng.fan@nxp.com \
    --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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.