crypto: talitos - Implement done interrupt mitigation

In talitos_interrupt, upon one done interrupt, mask further done interrupts,
and ack only any error interrupt.
In talitos_done, unmask done interrupts after completing processing.
In flush_channel, ack each done channel processed.
Keep done overflow interrupts masked because even though each pkt
is ack'ed, a few done overflows still occur.

Signed-off-by: Lee Nipper <lee.nipper@freescale.com>
Signed-off-by: Kim Phillips <kim.phillips@freescale.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
这个提交包含在:
Lee Nipper
2008-10-12 20:29:34 +08:00
提交者 Herbert Xu
父节点 40405f10b8
当前提交 1c2e8811ee
修改 2 个文件,包含 24 行新增9 行删除

查看文件

@@ -319,9 +319,11 @@ static void flush_channel(struct device *dev, int ch, int error, int reset_ch)
/* descriptors with their done bits set don't get the error */
rmb();
if ((request->desc->hdr & DESC_HDR_DONE) == DESC_HDR_DONE)
if ((request->desc->hdr & DESC_HDR_DONE) == DESC_HDR_DONE) {
status = 0;
else
/* Ack each pkt completed on channel */
out_be32(priv->reg + TALITOS_ICR, (1 << (ch * 2)));
} else
if (!error)
break;
else
@@ -369,6 +371,11 @@ static void talitos_done(unsigned long data)
for (ch = 0; ch < priv->num_channels; ch++)
flush_channel(dev, ch, 0, 0);
/* At this point, all completed channels have been processed.
* Unmask done interrupts for channels completed later on.
*/
setbits32(priv->reg + TALITOS_IMR, TALITOS_IMR_DONE);
}
/*
@@ -557,15 +564,22 @@ static irqreturn_t talitos_interrupt(int irq, void *data)
isr = in_be32(priv->reg + TALITOS_ISR);
isr_lo = in_be32(priv->reg + TALITOS_ISR_LO);
/* ack */
out_be32(priv->reg + TALITOS_ICR, isr);
out_be32(priv->reg + TALITOS_ICR_LO, isr_lo);
if (unlikely((isr & ~TALITOS_ISR_CHDONE) || isr_lo)) {
/*
* Acknowledge error interrupts here.
* Done interrupts are ack'ed as part of done_task.
*/
out_be32(priv->reg + TALITOS_ICR, isr);
out_be32(priv->reg + TALITOS_ICR_LO, isr_lo);
if (unlikely((isr & ~TALITOS_ISR_CHDONE) || isr_lo))
talitos_error((unsigned long)data, isr, isr_lo);
else
if (likely(isr & TALITOS_ISR_CHDONE))
} else
if (likely(isr & TALITOS_ISR_CHDONE)) {
/* mask further done interrupts. */
clrbits32(priv->reg + TALITOS_IMR, TALITOS_IMR_DONE);
/* done_task will unmask done interrupts at exit */
tasklet_schedule(&priv->done_task);
}
return (isr || isr_lo) ? IRQ_HANDLED : IRQ_NONE;
}