204 lines
6.3 KiB
Diff
204 lines
6.3 KiB
Diff
From ea253b8ebdb3f33985668040845046c23aecab3d Mon Sep 17 00:00:00 2001
|
|
From: donghuawei <donghuawei@eswincomputing.com>
|
|
Date: Thu, 26 Sep 2024 11:27:58 +0800
|
|
Subject: [PATCH 177/219] fix: dsp driver need cancel scheduled work
|
|
|
|
Changelogs:
|
|
when suspend, driver need flush work for scheduled work have
|
|
done.
|
|
|
|
Signed-off-by: donghuawei <donghuawei@eswincomputing.com>
|
|
---
|
|
drivers/soc/eswin/ai_driver/dsp/dsp_ioctl.c | 5 ++-
|
|
drivers/soc/eswin/ai_driver/dsp/dsp_main.c | 31 ++++++++++++++-----
|
|
.../soc/eswin/ai_driver/dsp/dsp_platform.c | 23 ++++++++++++++
|
|
.../soc/eswin/ai_driver/dsp/dsp_platform.h | 1 +
|
|
.../eswin/ai_driver/dsp/dsp_platform_sim.c | 5 +++
|
|
5 files changed, 57 insertions(+), 8 deletions(-)
|
|
|
|
diff --git a/drivers/soc/eswin/ai_driver/dsp/dsp_ioctl.c b/drivers/soc/eswin/ai_driver/dsp/dsp_ioctl.c
|
|
index 1edac591f642..c42c9ec251c7 100644
|
|
--- a/drivers/soc/eswin/ai_driver/dsp/dsp_ioctl.c
|
|
+++ b/drivers/soc/eswin/ai_driver/dsp/dsp_ioctl.c
|
|
@@ -1170,7 +1170,10 @@ static int dsp_open(struct inode *inode, struct file *flip)
|
|
int ret;
|
|
|
|
dsp_info("%s %d, pid %d\n", __func__, __LINE__, current->pid);
|
|
-
|
|
+ if (dsp->off) {
|
|
+ dsp_err("%s, %d, dsp fw is offline.\n", __func__, __LINE__);
|
|
+ return -EIO;
|
|
+ }
|
|
ret = es_dsp_pm_get_sync(dsp);
|
|
if (ret < 0) {
|
|
dsp_err("%s, %d, pm get sync err, ret=%d.\n", __func__,
|
|
diff --git a/drivers/soc/eswin/ai_driver/dsp/dsp_main.c b/drivers/soc/eswin/ai_driver/dsp/dsp_main.c
|
|
index 4a68e4bf3559..130479f6d778 100644
|
|
--- a/drivers/soc/eswin/ai_driver/dsp/dsp_main.c
|
|
+++ b/drivers/soc/eswin/ai_driver/dsp/dsp_main.c
|
|
@@ -329,7 +329,6 @@ irqreturn_t dsp_irq_handler(void *msg_data, struct es_dsp *dsp)
|
|
}
|
|
}
|
|
|
|
- dsp->current_task = NULL;
|
|
spin_unlock_irqrestore(&dsp->send_lock, flags);
|
|
BUG_ON(timer_pending(&dsp->task_timer));
|
|
|
|
@@ -338,12 +337,14 @@ irqreturn_t dsp_irq_handler(void *msg_data, struct es_dsp *dsp)
|
|
|
|
req->d2h_msg = *msg;
|
|
dsp_complete_work(dsp, req);
|
|
+ dsp->current_task = NULL;
|
|
|
|
dsp_debug("%s, current task req = 0x%px.\n", __func__, req);
|
|
dsp_info("op name:%s take time:%lld\n", dsp->stats->last_op_name,
|
|
dsp->stats->last_task_time);
|
|
-
|
|
- dsp_schedule_task(dsp);
|
|
+ if (dsp->off == false) {
|
|
+ dsp_schedule_task(dsp);
|
|
+ }
|
|
return IRQ_HANDLED;
|
|
}
|
|
EXPORT_SYMBOL(dsp_irq_handler);
|
|
@@ -717,10 +718,23 @@ int __maybe_unused dsp_suspend(struct device *dev)
|
|
if (ret < 0) {
|
|
return ret;
|
|
}
|
|
+ dsp->off = true;
|
|
+
|
|
+ if (dsp->current_task != NULL) {
|
|
+ ret = wait_for_current_tsk_done(dsp);
|
|
+ if (ret) {
|
|
+ dsp_err("%s, %d, cannot wait for current task done, ret = %d.\n", __func__, __LINE__, ret);
|
|
+ dsp->off = false;
|
|
+ return ret;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ flush_work(&dsp->task_work);
|
|
+
|
|
+ dsp_disable_irq(dsp);
|
|
es_dsp_hw_uninit(dsp);
|
|
|
|
dsp_release_firmware(dsp);
|
|
- dsp_disable_irq(dsp);
|
|
dsp_halt(dsp);
|
|
|
|
pm_runtime_mark_last_busy(dsp->dev);
|
|
@@ -728,7 +742,7 @@ int __maybe_unused dsp_suspend(struct device *dev)
|
|
win2030_tbu_power(dsp->dev, false);
|
|
es_dsp_clk_disable(dsp);
|
|
dsp_disable_mbox_clock(dsp);
|
|
- dsp_debug("%s, %d, dsp core%d generic suspend done.\n", __func__,
|
|
+ dsp_debug("%s, %d, dsp core%d generic suspend done.\n", __func__,
|
|
__LINE__, dsp->process_id);
|
|
return 0;
|
|
}
|
|
@@ -737,8 +751,6 @@ int __maybe_unused dsp_resume(struct device *dev)
|
|
{
|
|
struct es_dsp *dsp = dev_get_drvdata(dev);
|
|
int ret;
|
|
- if (dsp->off)
|
|
- goto out;
|
|
|
|
dsp_debug("%s, dsp core%d generic resuming..\n\n", __func__,
|
|
dsp->process_id);
|
|
@@ -775,6 +787,8 @@ int __maybe_unused dsp_resume(struct device *dev)
|
|
pm_runtime_put_autosuspend(dsp->dev);
|
|
dsp_debug("dsp_core%d Generic resume ok, dsp->off=%d.\n",
|
|
dsp->process_id, dsp->off);
|
|
+ dsp->off = false;
|
|
+ dsp_schedule_task(dsp);
|
|
return 0;
|
|
err_firm:
|
|
es_dsp_hw_uninit(dsp);
|
|
@@ -792,6 +806,7 @@ int __maybe_unused dsp_runtime_suspend(struct device *dev)
|
|
struct es_dsp *dsp = dev_get_drvdata(dev);
|
|
dsp_debug("%s, dsp core%d runtime suspend.\n", __func__,
|
|
dsp->process_id);
|
|
+
|
|
win2030_tbu_power(dev, false);
|
|
es_dsp_clk_disable(dsp);
|
|
return 0;
|
|
@@ -1096,6 +1111,8 @@ static int es_dsp_hw_remove(struct platform_device *pdev)
|
|
if (NULL != dsp->miscdev.this_device) {
|
|
misc_deregister(&dsp->miscdev);
|
|
}
|
|
+
|
|
+ cancel_work_sync(&dsp->task_work);
|
|
es_dsp_hw_uninit(dsp);
|
|
|
|
pm_runtime_disable(dsp->dev);
|
|
diff --git a/drivers/soc/eswin/ai_driver/dsp/dsp_platform.c b/drivers/soc/eswin/ai_driver/dsp/dsp_platform.c
|
|
index a2a360d181e9..055428dfaba1 100644
|
|
--- a/drivers/soc/eswin/ai_driver/dsp/dsp_platform.c
|
|
+++ b/drivers/soc/eswin/ai_driver/dsp/dsp_platform.c
|
|
@@ -352,6 +352,28 @@ void es_dsp_release(struct es_dsp_hw *hw)
|
|
return;
|
|
}
|
|
|
|
+int wait_for_current_tsk_done(struct es_dsp *dsp)
|
|
+{
|
|
+ const int sleep_retries = 5;
|
|
+ const int wake_retries = 20;
|
|
+ int i, j;
|
|
+
|
|
+ for (i = 0; i < sleep_retries; i++) {
|
|
+ for (j = 0; j < wake_retries; j++) {
|
|
+ if (dsp->current_task == NULL) {
|
|
+ break;
|
|
+ }
|
|
+ usleep_range(100, 5000);
|
|
+ }
|
|
+
|
|
+ if (j < wake_retries) {
|
|
+ return 0;
|
|
+ }
|
|
+ }
|
|
+ dsp_err("%s, %d, Timeout for wait current task done.\n", __func__, __LINE__);
|
|
+ return -ETIMEDOUT;
|
|
+}
|
|
+
|
|
static int check_dsp_fw_state(struct es_dsp *dsp)
|
|
{
|
|
struct dsp_fw_state_t *dsp_state = (struct dsp_fw_state_t *)dsp->dsp_fw_state_base;
|
|
@@ -1237,6 +1259,7 @@ void dsp_disable_irq(struct es_dsp *dsp)
|
|
if (dsp->mbox_irq) {
|
|
disable_irq(dsp->mbox_irq);
|
|
}
|
|
+ synchronize_irq(dsp->mbox_irq);
|
|
}
|
|
|
|
int dsp_enable_irq(struct es_dsp *dsp)
|
|
diff --git a/drivers/soc/eswin/ai_driver/dsp/dsp_platform.h b/drivers/soc/eswin/ai_driver/dsp/dsp_platform.h
|
|
index b01f21bc7055..e0b3bf847d3f 100644
|
|
--- a/drivers/soc/eswin/ai_driver/dsp/dsp_platform.h
|
|
+++ b/drivers/soc/eswin/ai_driver/dsp/dsp_platform.h
|
|
@@ -55,5 +55,6 @@ int dsp_enable_irq(struct es_dsp *dsp);
|
|
void dsp_disable_irq(struct es_dsp *dsp);
|
|
void dsp_disable_mbox_clock(struct es_dsp *dsp);
|
|
int dsp_enable_mbox_clock(struct es_dsp *dsp);
|
|
+int wait_for_current_tsk_done(struct es_dsp *dsp);
|
|
|
|
#endif
|
|
diff --git a/drivers/soc/eswin/ai_driver/dsp/dsp_platform_sim.c b/drivers/soc/eswin/ai_driver/dsp/dsp_platform_sim.c
|
|
index fd2edd5fa926..8c36e90e20f6 100644
|
|
--- a/drivers/soc/eswin/ai_driver/dsp/dsp_platform_sim.c
|
|
+++ b/drivers/soc/eswin/ai_driver/dsp/dsp_platform_sim.c
|
|
@@ -498,6 +498,11 @@ int dsp_alloc_hw(struct platform_device *pdev, struct es_dsp *dsp)
|
|
return 0;
|
|
}
|
|
|
|
+int wait_for_current_tsk_done(struct es_dsp *dsp)
|
|
+{
|
|
+ return 0;
|
|
+}
|
|
+
|
|
void dsp_free_hw(struct es_dsp *dsp)
|
|
{
|
|
struct es_dsp_hw *hw = (struct es_dsp_hw *)dsp->hw_arg;
|
|
--
|
|
2.47.0
|
|
|