in core.c [1160:1212]
int most_stop_channel(struct most_interface *iface, int id,
struct most_component *comp)
{
struct most_channel *c;
if (unlikely((!iface) || (id >= iface->num_channels) || (id < 0))) {
pr_err("Bad interface or index out of range\n");
return -EINVAL;
}
c = iface->p->channel[id];
if (unlikely(!c))
return -EINVAL;
mutex_lock(&c->start_mutex);
if (c->pipe0.refs + c->pipe1.refs >= 2)
goto out;
if (c->hdm_enqueue_task)
kthread_stop(c->hdm_enqueue_task);
c->hdm_enqueue_task = NULL;
if (iface->mod)
module_put(iface->mod);
c->is_poisoned = true;
if (c->iface->poison_channel(c->iface, c->channel_id)) {
dev_err(&c->dev, "Failed to stop channel %d of interface %s\n", c->channel_id,
c->iface->description);
mutex_unlock(&c->start_mutex);
return -EAGAIN;
}
flush_trash_fifo(c);
flush_channel_fifos(c);
#ifdef CMPL_INTERRUPTIBLE
if (wait_for_completion_interruptible(&c->cleanup)) {
dev_err(&c->dev, "Interrupted while cleaning up channel %d\n", c->channel_id);
mutex_unlock(&c->start_mutex);
return -EINTR;
}
#else
wait_for_completion(&c->cleanup);
#endif
c->is_poisoned = false;
out:
if (comp == c->pipe0.comp)
c->pipe0.refs--;
if (comp == c->pipe1.comp)
c->pipe1.refs--;
mutex_unlock(&c->start_mutex);
return 0;
}