[PATCH v4] fpga: stratix10-soc: Fix SVC mailbox handling during reconfiguration
[email protected] Mon, 29 Jun 2026 23:57:19 -0700
| Newsgroups | org.kernel.vger.linux-fpga,org.kernel.vger.linux-kernel |
|---|---|
| Message-ID | <8768ce3260489c9febdfce08e27d03f5f5ed9c33.1782801986.git.tze.yee.ng@altera.com> |
From: Tien Sung Ang <[email protected]> Fix incorrect stratix10_svc_done() usage during FPGA reconfiguration. Do not call stratix10_svc_done() at the end of write_init() on success, so the SVC session remains active through write() and write_complete(). Call stratix10_svc_done() on failure in write_init() and write() so the shared SVC mailbox is released when reconfiguration aborts, allowing coexistence with other SVC clients such as soc64-hwmon. Fixes: e7eef1d7633a ("fpga: add intel stratix10 soc fpga manager driver") Cc: [email protected] # 5.1+ Signed-off-by: Tien Sung Ang <[email protected]> Signed-off-by: Tze Yee Ng <[email protected]> --- Changes in v4: - Restructure write_init() per review: return 0 on success, single init_error path for stratix10_svc_done(). - Do not assign wait_for_completion_timeout() result to ret; removes the need for ret = 0. - Revert PTR_ERR(kbuf) to -ENOMEM change; keep PTR_ERR(kbuf). --- drivers/fpga/stratix10-soc.c | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/drivers/fpga/stratix10-soc.c b/drivers/fpga/stratix10-soc.c index 0a295ccf1644..b8ec2e6f615f 100644 --- a/drivers/fpga/stratix10-soc.c +++ b/drivers/fpga/stratix10-soc.c @@ -195,20 +195,18 @@ static int s10_ops_write_init(struct fpga_manager *mgr, ret = s10_svc_send_msg(priv, COMMAND_RECONFIG, &ctype, sizeof(ctype)); if (ret < 0) - goto init_done; + goto init_error; - ret = wait_for_completion_timeout( - &priv->status_return_completion, S10_RECONFIG_TIMEOUT); - if (!ret) { + if (!wait_for_completion_timeout(&priv->status_return_completion, + S10_RECONFIG_TIMEOUT)) { dev_err(dev, "timeout waiting for RECONFIG_REQUEST\n"); ret = -ETIMEDOUT; - goto init_done; + goto init_error; } - ret = 0; if (!test_and_clear_bit(SVC_STATUS_OK, &priv->status)) { ret = -ETIMEDOUT; - goto init_done; + goto init_error; } /* Allocate buffers from the service layer's pool. */ @@ -217,14 +215,16 @@ static int s10_ops_write_init(struct fpga_manager *mgr, if (IS_ERR(kbuf)) { s10_free_buffers(mgr); ret = PTR_ERR(kbuf); - goto init_done; + goto init_error; } priv->svc_bufs[i].buf = kbuf; priv->svc_bufs[i].lock = 0; } -init_done: + return 0; + +init_error: stratix10_svc_done(priv->chan); return ret; } @@ -342,6 +342,9 @@ static int s10_ops_write(struct fpga_manager *mgr, const char *buf, if (!s10_free_buffers(mgr)) dev_err(dev, "%s not all buffers were freed\n", __func__); + if (ret < 0) + stratix10_svc_done(priv->chan); + return ret; } -- 2.43.7