crypto: talitos - done interrupt mitigation
PATCH 2/3 crypto: talitos - 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 <[email protected]>
Signed-off-by Kim Phillips <[email protected]>
--- drivers/crypto/talitos.c | 30 ++++++++++++++++++++++-------- drivers/crypto/talitos.h | 3 ++- 2 files changed, 24 insertions(+), 9 deletions(-)
drivers/crypto/talitos.c +22 -8
@@ -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 ; }
drivers/crypto/talitos.h +2 -1
@@ -37,7 +37,8 @@#define TALITOS_MCR_LO 0x1038#define TALITOS_MCR_SWR 0x1/* s/w reset */ #define TALITOS_IMR 0x1008/* interrupt mask register */ -#define TALITOS_IMR_INIT 0x10fff/* enable channel IRQs */ +#define TALITOS_IMR_INIT 0x100ff/* enable channel IRQs */ +#define TALITOS_IMR_DONE 0x00055/* done IRQs */ #define TALITOS_IMR_LO 0x100C#define TALITOS_IMR_LO_INIT 0x20000/* allow RNGU error IRQs */ #define TALITOS_ISR 0x1010/* interrupt status register */
Signature · 1 line
1.5.6.2