[Sound-open-firmware] [PATCH] cnl: gp-dma: fix gp-dma dead loop issue
Liam Girdwood
liam.r.girdwood at linux.intel.com
Thu Mar 1 11:22:12 CET 2018
On Thu, 2018-03-01 at 08:59 +0000, Wang, Rander wrote:
> Hi Liam,
>
> See my comments
>
> Thank you!
> Rander
> > -----Original Message-----
> > From: Liam Girdwood [mailto:liam.r.girdwood at linux.intel.com]
> > Sent: Wednesday, February 28, 2018 5:23 PM
> > To: Wang, Rander <rander.wang at intel.com>;
> > sound-open-firmware at alsa-project.org
> > Subject: Re: [Sound-open-firmware] [PATCH] cnl: gp-dma: fix gp-dma
> > dead loop
> > issue
> >
> > On Wed, 2018-02-28 at 16:52 +0800, Rander Wang wrote:
> > > In irq function, two dma would be checked which one is the
> > > interrupted
> > > one, so get it after check.
> > >
> > > Signed-off-by: Rander Wang <rander.wang at intel.com>
> > > ---
> > > src/drivers/dw-dma.c | 3 ++-
> > > 1 file changed, 2 insertions(+), 1 deletion(-)
> > >
> > > diff --git a/src/drivers/dw-dma.c b/src/drivers/dw-dma.c index
> > > be19e12..6fd46e0 100644
> > > --- a/src/drivers/dw-dma.c
> > > +++ b/src/drivers/dw-dma.c
> > > @@ -1034,7 +1034,7 @@ static int dw_dma_probe(struct dma *dma)
> >
> > static
> > > void dw_dma_irq_handler(void *data) {
> > > struct dma *dma = (struct dma *)data;
> > > - struct dma_pdata *p = dma_get_drvdata(dma);
> > > + struct dma_pdata *p;
> > > struct dma_sg_elem next;
> > > uint32_t status_tfr = 0;
> > > uint32_t status_block = 0;
> > > @@ -1058,6 +1058,7 @@ static void dw_dma_irq_handler(void *data)
> > > }
> > >
> > > tracev_dma("DIr");
> > > + p = dma_get_drvdata(dma);
> > >
> > > /* get the source of our IRQ. */
> > > status_block = dw_read(dma, DW_STATUS_BLOCK);
> >
> >
> > Iiuc, the IRQ for both DMACs on CNL is shared ? and we determine
> > which
> > DMAC has the IRQ by reading each status register above ?
> >
> > If so, this fails when both DMACs have IRQs at the same time.
>
> If only one core is enabled, the interrupt with the same irq level
> would trigger
> Irq function two times?
No, the IRQ line is ORed between both DMACs. Either or both will cause
and IRQ. Both status register must be read though.
>
> And if multicore is enabled, if two core received the interrupt at
> the same time,
> Maybe something wrong?
That is possible, but the IRQ should be masked in other cores.
Btw, this is wrong too:-
static int dw_dma_probe(struct dma *dma)
{
struct dma_pdata *dw_pdata;
struct dma *dmac = dma;
int i;
#ifdef CONFIG_CANNONLAKE
int j;
for (j = 0; j < MAX_GPDMA_COUNT; j++)
#endif
{
We dont need this for loop. dw_dma_probe () will be called in
platform.c for each DMAC.
>
> > Please do something like :-
> >
> > dw_dma_irq_handler_cnl()
> > {
> > dma = dmac0;
> >
> > /* read status for DMAC0 */
> > status_intr = dw_read(dma, DW_INTR_STATUS);
> > if (status_intr)
> > dw_dma_irq_handler(dma);
> >
> > dma = dmac1;
> >
> > /* read status for DMAC1 */
> > status_intr = dw_read(dma, DW_INTR_STATUS);
> > if (status_intr)
> > dw_dma_irq_handler(dma);
> > }
> >
> > Liam
More information about the Sound-open-firmware
mailing list