lkml.org 
[lkml]   [2020]   [Jul]   [5]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
From
Subject[PATCH v8 4/4] mailbox: mediatek: cmdq: clear task in channel before shutdown
Date
Do success callback in channel when shutdown. For those task not finish,
callback with error code thus client has chance to cleanup or reset.

Signed-off-by: Dennis YC Hsieh <dennis-yc.hsieh@mediatek.com>
Reviewed-by: CK Hu <ck.hu@mediatek.com>
Reviewed-by: Bibby Hsieh <bibby.hsieh@mediatek.com>
---
drivers/mailbox/mtk-cmdq-mailbox.c | 38 ++++++++++++++++++++++++++++++++++++
1 file changed, 38 insertions(+)

diff --git a/drivers/mailbox/mtk-cmdq-mailbox.c b/drivers/mailbox/mtk-cmdq-mailbox.c
index 08bd4f1eb469..484d4438cd83 100644
--- a/drivers/mailbox/mtk-cmdq-mailbox.c
+++ b/drivers/mailbox/mtk-cmdq-mailbox.c
@@ -349,6 +349,12 @@ static int cmdq_mbox_send_data(struct mbox_chan *chan, void *data)

if (list_empty(&thread->task_busy_list)) {
WARN_ON(clk_enable(cmdq->clock) < 0);
+ /*
+ * The thread reset will clear thread related register to 0,
+ * including pc, end, priority, irq, suspend and enable. Thus
+ * set CMDQ_THR_ENABLED to CMDQ_THR_ENABLE_TASK will enable
+ * thread and make it running.
+ */
WARN_ON(cmdq_thread_reset(cmdq, thread) < 0);

writel(task->pa_base >> cmdq->shift_pa,
@@ -391,6 +397,38 @@ static int cmdq_mbox_startup(struct mbox_chan *chan)

static void cmdq_mbox_shutdown(struct mbox_chan *chan)
{
+ struct cmdq_thread *thread = (struct cmdq_thread *)chan->con_priv;
+ struct cmdq *cmdq = dev_get_drvdata(chan->mbox->dev);
+ struct cmdq_task *task, *tmp;
+ unsigned long flags;
+
+ spin_lock_irqsave(&thread->chan->lock, flags);
+ if (list_empty(&thread->task_busy_list))
+ goto done;
+
+ WARN_ON(cmdq_thread_suspend(cmdq, thread) < 0);
+
+ /* make sure executed tasks have success callback */
+ cmdq_thread_irq_handler(cmdq, thread);
+ if (list_empty(&thread->task_busy_list))
+ goto done;
+
+ list_for_each_entry_safe(task, tmp, &thread->task_busy_list,
+ list_entry) {
+ cmdq_task_exec_done(task, CMDQ_CB_ERROR);
+ kfree(task);
+ }
+
+ cmdq_thread_disable(cmdq, thread);
+ clk_disable(cmdq->clock);
+done:
+ /*
+ * The thread->task_busy_list empty means thread already disable. The
+ * cmdq_mbox_send_data() always reset thread which clear disable and
+ * suspend statue when first pkt send to channel, so there is no need
+ * to do any operation here, only unlock and leave.
+ */
+ spin_unlock_irqrestore(&thread->chan->lock, flags);
}

static int cmdq_mbox_flush(struct mbox_chan *chan, unsigned long timeout)
--
1.7.9.5
\
 
 \ /
  Last update: 2020-07-05 08:37    [W:0.040 / U:0.376 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site