dma: edma: Leave linked to Null slot instead of DUMMY slot

Dummy slot has been used as a way for missed-events not to be
reported as missing. This has been particularly troublesome for cases
where we might want to temporarily pause all incoming events.

For EDMA DMAC, there is no way to do any such pausing of events as
the occurence of the "next" event is not software controlled.
Using "edma_pause" in IRQ handlers doesn't help as by then the event
in concern from the slave is already missed.

Linking a dummy slot, is seen to absorb these events which we didn't
want to miss. So we don't link to dummy, but instead leave it linked
to NULL set, allow an error condition and detect the channel that
missed it.

Consider the case where we have a scatter-list like:
SG1->SG2->SG3->SG4->SG5->SG6->Null

For ex, for a MAX_NR_SG of 2, earlier we were splitting this as:
SG1->SG2->Null
SG3->SG4->Null
SG5->SG6->Null

Now we split it as
SG1->SG2->Null
SG3->SG4->Null
SG5->SG6->Dummy

This approach results in lesser unwanted interrupts that occur
for the last list split. The Dummy slot has the property of not
raising an error condition if events are missed unlike the Null
slot. We are OK with this as we're done with processing the
whole list once we reach Dummy.

Signed-off-by: Joel Fernandes <joelf@ti.com>
[modifed duplicate s-o-b & patch title]
Signed-off-by: Vinod Koul <vinod.koul@intel.com>
This commit is contained in:
Joel Fernandes 2013-08-29 18:05:44 -05:00 коммит произвёл Vinod Koul
Родитель c5f47990aa
Коммит b267b3bc1e
1 изменённых файлов: 8 добавлений и 3 удалений

Просмотреть файл

@ -158,13 +158,18 @@ static void edma_execute(struct edma_chan *echan)
/* Link to the previous slot if not the last set */ /* Link to the previous slot if not the last set */
if (i != (nslots - 1)) if (i != (nslots - 1))
edma_link(echan->slot[i], echan->slot[i+1]); edma_link(echan->slot[i], echan->slot[i+1]);
/* Final pset links to the dummy pset */
else
edma_link(echan->slot[i], echan->ecc->dummy_slot);
} }
edesc->processed += nslots; edesc->processed += nslots;
/*
* If this is either the last set in a set of SG-list transactions
* then setup a link to the dummy slot, this results in all future
* events being absorbed and that's OK because we're done
*/
if (edesc->processed == edesc->pset_nr)
edma_link(echan->slot[nslots-1], echan->ecc->dummy_slot);
edma_resume(echan->ch_num); edma_resume(echan->ch_num);
if (edesc->processed <= MAX_NR_SG) { if (edesc->processed <= MAX_NR_SG) {