diff --git a/src/schedule/ll_schedule.c b/src/schedule/ll_schedule.c index a650cd065cea..d06d8b15c811 100644 --- a/src/schedule/ll_schedule.c +++ b/src/schedule/ll_schedule.c @@ -107,11 +107,6 @@ static void schedule_ll_task_update_start(struct ll_schedule_data *sch, static void schedule_ll_task_done(struct ll_schedule_data *sch, struct task *task) { - /* Remove from the task list, schedule_task_cancel() won't handle it again */ - list_item_del(&task->list); - - domain_unregister(sch->domain, task, atomic_sub(&sch->num_tasks, 1) - 1); - tr_info(&ll_tr, "task complete %p %pU", task, task->uid); tr_info(&ll_tr, "num_tasks %d total_num_tasks %d", atomic_read(&sch->num_tasks), @@ -142,6 +137,10 @@ static void schedule_ll_tasks_execute(struct ll_schedule_data *sch) /* do we need to reschedule this task */ if (task->state == SOF_TASK_STATE_COMPLETED) { + /* + * keep the task in the list and the subsequent call to + * schedule_ll_task_cancel() will clean it up. + */ schedule_ll_task_done(sch, task); } else { /* update task's start time */ diff --git a/src/schedule/timer_domain.c b/src/schedule/timer_domain.c index 8d30dc26f321..6d5cc125547b 100644 --- a/src/schedule/timer_domain.c +++ b/src/schedule/timer_domain.c @@ -67,12 +67,21 @@ static int timer_domain_register(struct ll_schedule_domain *domain, static int timer_domain_unregister(struct ll_schedule_domain *domain, struct task *task, uint32_t num_tasks) { - /* - * domain_unregister() can be called from the domain handler itself, - * and we cannot unregister the timer interrupt handler from the handler - * itself. Keep the interrupt registered but disabled. This assumes that - * the handler is at least not unloaded. - */ + struct timer_domain *timer_domain = ll_sch_domain_get_pdata(domain); + int core = cpu_get_id(); + + tr_dbg(&ll_tr, "timer_domain_unregister()"); + + /* tasks still registered on this core */ + if (!timer_domain->arg[core] || num_tasks) + return 0; + + tr_info(&ll_tr, "timer_domain_unregister domain->type %d domain->clk %d", + domain->type, domain->clk); + + timer_unregister(timer_domain->timer, timer_domain->arg[core]); + + timer_domain->arg[core] = NULL; return 0; }