mirror of https://github.com/thesofproject/sof.git
schedule: zephyr_dma_domain: Do not use a registered channel
Current implementation only checks if a channel is used with current interrupt. But that channel might have been registered with another interrupt earlier. So, we need a way to skip channels already used. For this, we iterate over all registered interrupts and check existing registered channels. This fixes scenarios where running: $ arecord -Dhw:0,0 -f S32 -c 2 -r 48000 -t raw | aplay -Dhw:0,0 -f S32_LE -c 2 -r 48000 will result in an I/O error. Signed-off-by: Daniel Baluta <daniel.baluta@nxp.com>
This commit is contained in:
parent
b7d7fb0ed2
commit
1a8b1bf60c
|
@ -239,6 +239,26 @@ static struct zephyr_dma_domain_irq *fetch_irq_data(struct zephyr_dma_domain *do
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool chan_is_registered(struct zephyr_dma_domain *domain, struct dma_chan_data *chan)
|
||||||
|
{
|
||||||
|
struct zephyr_dma_domain_irq *irq_data;
|
||||||
|
struct zephyr_dma_domain_channel *chan_data;
|
||||||
|
struct list_item *i, *j;
|
||||||
|
|
||||||
|
list_for_item(i, &domain->irqs) {
|
||||||
|
irq_data = container_of(i, struct zephyr_dma_domain_irq, list);
|
||||||
|
|
||||||
|
list_for_item(j, &irq_data->channels) {
|
||||||
|
chan_data = container_of(j, struct zephyr_dma_domain_channel, list);
|
||||||
|
|
||||||
|
if (chan_data->channel == chan)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
static int register_dma_irq(struct zephyr_dma_domain *domain,
|
static int register_dma_irq(struct zephyr_dma_domain *domain,
|
||||||
struct zephyr_dma_domain_irq **irq_data,
|
struct zephyr_dma_domain_irq **irq_data,
|
||||||
struct zephyr_dma_domain_thread *dt,
|
struct zephyr_dma_domain_thread *dt,
|
||||||
|
@ -273,6 +293,10 @@ static int register_dma_irq(struct zephyr_dma_domain *domain,
|
||||||
if (core != crt_chan->core)
|
if (core != crt_chan->core)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
/* skip is DMA chan is already registered with domain */
|
||||||
|
if (chan_is_registered(domain, crt_chan))
|
||||||
|
continue;
|
||||||
|
|
||||||
/* get IRQ number for current channel */
|
/* get IRQ number for current channel */
|
||||||
irq = interrupt_get_irq(dma_chan_irq(crt_dma, j),
|
irq = interrupt_get_irq(dma_chan_irq(crt_dma, j),
|
||||||
dma_chan_irq_name(crt_dma, j));
|
dma_chan_irq_name(crt_dma, j));
|
||||||
|
|
Loading…
Reference in New Issue