Commit 88499698 authored by Dennis YC Hsieh's avatar Dennis YC Hsieh Committed by Jassi Brar

mailbox: mediatek: cmdq: clear task in channel before shutdown

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: default avatarDennis YC Hsieh <dennis-yc.hsieh@mediatek.com>
Reviewed-by: default avatarCK Hu <ck.hu@mediatek.com>
Reviewed-by: default avatarBibby Hsieh <bibby.hsieh@mediatek.com>
Signed-off-by: default avatarJassi Brar <jaswinder.singh@linaro.org>
parent bb2b06e0
......@@ -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)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment