[<prev] [next>] [day] [month] [year] [list]
Message-ID: <669f87ac9348a0532589f17a625664cec68e0059.1761796187.git.adrianhoyin.ng@altera.com>
Date: Thu, 30 Oct 2025 11:52:14 +0800
From: adrianhoyin.ng@...era.com
To: dinguyen@...nel.org,
linux-kernel@...r.kernel.org
Cc: adrianhoyin.ng@...era.com
Subject: [PATCH] firmware: stratix10-svc: Reduce polling interval for command status
From: Adrian Ng Ho Yin <adrianhoyin.ng@...era.com>
The service controller currently polls FPGA configuration status at a
fixed 1 second interval until the 30 second timeout expires. This leads
to slow response time for fast-returning commands and unnecessary delay
before reporting completion.
Introduce two polling modes:
- Fast polling: 20 ms interval for up to 50 iterations (≈1s total)
- Slow polling: 500 ms interval for up to 29 seconds
A new helper, svc_cmd_poll_status(), abstracts the polling logic and
replaces the existing loop in svc_thread_cmd_config_status(). This allows
the driver to respond quickly to short operations while still handling
long-running configuration commands within the same overall timeout
window.
Signed-off-by: Adrian Ng Ho Yin <adrianhoyin.ng@...era.com>
---
drivers/firmware/stratix10-svc.c | 91 +++++++++++++++++++++++---------
1 file changed, 67 insertions(+), 24 deletions(-)
diff --git a/drivers/firmware/stratix10-svc.c b/drivers/firmware/stratix10-svc.c
index 3acfa067c5dd..adf04ea56735 100644
--- a/drivers/firmware/stratix10-svc.c
+++ b/drivers/firmware/stratix10-svc.c
@@ -36,11 +36,27 @@
* FPGA_CONFIG_STATUS_TIMEOUT_SEC - poll the FPGA configuration status,
* service layer will return error to FPGA manager when timeout occurs,
* timeout is set to 30 seconds (30 * 1000) at Intel Stratix10 SoC.
+ *
+ * SVC_POLL_INTERVAL_MS_FAST - interval for polling the service status
+ * at secure world for fast response commands. Interval is set to 20ms.
+ *
+ * SVC_POLL_INTERVAL_MS_SLOW - interval for polling the service status
+ * at secure world for slow response commands. Interval is set to 500ms.
+ *
+ * SVC_POLL_COUNT_FAST - number of count for polling service status for
+ * fast response commands. Count is set to 50 (50*20ms=1sec)
+ *
+ * SVC_POLL_COUNT_SLOW - number of count for polling service status for
+ * slow response commands. Count is set to 58 (58*500ms=29sec)
*/
#define SVC_NUM_DATA_IN_FIFO 32
#define SVC_NUM_CHANNEL 4
#define FPGA_CONFIG_DATA_CLAIM_TIMEOUT_MS 200
#define FPGA_CONFIG_STATUS_TIMEOUT_SEC 30
+#define SVC_POLL_INTERVAL_MS_FAST 20
+#define SVC_POLL_INTERVAL_MS_SLOW 500
+#define SVC_POLL_COUNT_FAST 50
+#define SVC_POLL_COUNT_SLOW 58
#define BYTE_TO_WORD_SIZE 4
/* stratix10 service layer clients */
@@ -370,6 +386,47 @@ static void svc_thread_cmd_data_claim(struct stratix10_svc_controller *ctrl,
wait_for_completion_timeout(&ctrl->complete_status, timeout));
}
+/**
+ * svc_cmd_poll_status() - poll for service status
+ * @p_data: pointer to service data structure
+ * @ctrl: pointer to service layer controller
+ * @res: pointer to store response
+ * @poll_count: pointer to poll count value
+ * @poll_interval_in_ms: interval value in milliseconds
+ *
+ * Check whether the service at secure world has completed, and then inform the
+ * response.
+ */
+static void svc_cmd_poll_status(struct stratix10_svc_data *p_data,
+ struct stratix10_svc_controller *ctrl,
+ struct arm_smccc_res *res,
+ int *poll_count, int poll_interval_in_ms)
+{
+ unsigned long a0, a1, a2;
+
+ a0 = INTEL_SIP_SMC_FPGA_CONFIG_ISDONE;
+ a1 = (unsigned long)p_data->paddr;
+ a2 = (unsigned long)p_data->size;
+
+ if (p_data->command == COMMAND_POLL_SERVICE_STATUS)
+ a0 = INTEL_SIP_SMC_SERVICE_COMPLETED;
+
+ while (*poll_count) {
+ ctrl->invoke_fn(a0, a1, a2, 0, 0, 0, 0, 0, res);
+ if (res->a0 == INTEL_SIP_SMC_STATUS_OK ||
+ res->a0 == INTEL_SIP_SMC_STATUS_ERROR ||
+ res->a0 == INTEL_SIP_SMC_STATUS_REJECTED)
+ break;
+
+ /*
+ * request is still in progress, go to sleep then
+ * poll again
+ */
+ msleep(poll_interval_in_ms);
+ (*poll_count)--;
+ }
+}
+
/**
* svc_thread_cmd_config_status() - check configuration status
* @ctrl: pointer to service layer controller
@@ -384,8 +441,7 @@ static void svc_thread_cmd_config_status(struct stratix10_svc_controller *ctrl,
struct stratix10_svc_cb_data *cb_data)
{
struct arm_smccc_res res;
- int count_in_sec;
- unsigned long a0, a1, a2;
+ int poll_count;
cb_data->kaddr1 = NULL;
cb_data->kaddr2 = NULL;
@@ -394,30 +450,17 @@ static void svc_thread_cmd_config_status(struct stratix10_svc_controller *ctrl,
pr_debug("%s: polling config status\n", __func__);
- a0 = INTEL_SIP_SMC_FPGA_CONFIG_ISDONE;
- a1 = (unsigned long)p_data->paddr;
- a2 = (unsigned long)p_data->size;
-
- if (p_data->command == COMMAND_POLL_SERVICE_STATUS)
- a0 = INTEL_SIP_SMC_SERVICE_COMPLETED;
-
- count_in_sec = FPGA_CONFIG_STATUS_TIMEOUT_SEC;
- while (count_in_sec) {
- ctrl->invoke_fn(a0, a1, a2, 0, 0, 0, 0, 0, &res);
- if ((res.a0 == INTEL_SIP_SMC_STATUS_OK) ||
- (res.a0 == INTEL_SIP_SMC_STATUS_ERROR) ||
- (res.a0 == INTEL_SIP_SMC_STATUS_REJECTED))
- break;
-
- /*
- * request is still in progress, wait one second then
- * poll again
- */
- msleep(1000);
- count_in_sec--;
+ poll_count = SVC_POLL_COUNT_FAST;
+ svc_cmd_poll_status(p_data, ctrl, &res, &poll_count,
+ SVC_POLL_INTERVAL_MS_FAST);
+ /* Increased poll interval if response is still not ready */
+ if (!poll_count) {
+ poll_count = SVC_POLL_COUNT_SLOW;
+ svc_cmd_poll_status(p_data, ctrl, &res, &poll_count,
+ SVC_POLL_INTERVAL_MS_SLOW);
}
- if (!count_in_sec) {
+ if (!poll_count) {
pr_err("%s: poll status timeout\n", __func__);
cb_data->status = BIT(SVC_STATUS_BUSY);
} else if (res.a0 == INTEL_SIP_SMC_STATUS_OK) {
--
2.49.GIT
Powered by blists - more mailing lists