diff options
-rw-r--r-- | drivers/crypto/talitos.c | 30 | ||||
-rw-r--r-- | drivers/crypto/talitos.h | 3 |
2 files changed, 24 insertions, 9 deletions
diff --git a/drivers/crypto/talitos.c b/drivers/crypto/talitos.c index c429f684c79d..b5c2c9340a9c 100644 --- a/drivers/crypto/talitos.c +++ b/drivers/crypto/talitos.c | |||
@@ -319,9 +319,11 @@ static void flush_channel(struct device *dev, int ch, int error, int reset_ch) | |||
319 | 319 | ||
320 | /* descriptors with their done bits set don't get the error */ | 320 | /* descriptors with their done bits set don't get the error */ |
321 | rmb(); | 321 | rmb(); |
322 | if ((request->desc->hdr & DESC_HDR_DONE) == DESC_HDR_DONE) | 322 | if ((request->desc->hdr & DESC_HDR_DONE) == DESC_HDR_DONE) { |
323 | status = 0; | 323 | status = 0; |
324 | else | 324 | /* Ack each pkt completed on channel */ |
325 | out_be32(priv->reg + TALITOS_ICR, (1 << (ch * 2))); | ||
326 | } else | ||
325 | if (!error) | 327 | if (!error) |
326 | break; | 328 | break; |
327 | else | 329 | else |
@@ -369,6 +371,11 @@ static void talitos_done(unsigned long data) | |||
369 | 371 | ||
370 | for (ch = 0; ch < priv->num_channels; ch++) | 372 | for (ch = 0; ch < priv->num_channels; ch++) |
371 | flush_channel(dev, ch, 0, 0); | 373 | flush_channel(dev, ch, 0, 0); |
374 | |||
375 | /* At this point, all completed channels have been processed. | ||
376 | * Unmask done interrupts for channels completed later on. | ||
377 | */ | ||
378 | setbits32(priv->reg + TALITOS_IMR, TALITOS_IMR_DONE); | ||
372 | } | 379 | } |
373 | 380 | ||
374 | /* | 381 | /* |
@@ -557,15 +564,22 @@ static irqreturn_t talitos_interrupt(int irq, void *data) | |||
557 | isr = in_be32(priv->reg + TALITOS_ISR); | 564 | isr = in_be32(priv->reg + TALITOS_ISR); |
558 | isr_lo = in_be32(priv->reg + TALITOS_ISR_LO); | 565 | isr_lo = in_be32(priv->reg + TALITOS_ISR_LO); |
559 | 566 | ||
560 | /* ack */ | 567 | if (unlikely((isr & ~TALITOS_ISR_CHDONE) || isr_lo)) { |
561 | out_be32(priv->reg + TALITOS_ICR, isr); | 568 | /* |
562 | out_be32(priv->reg + TALITOS_ICR_LO, isr_lo); | 569 | * Acknowledge error interrupts here. |
570 | * Done interrupts are ack'ed as part of done_task. | ||
571 | */ | ||
572 | out_be32(priv->reg + TALITOS_ICR, isr); | ||
573 | out_be32(priv->reg + TALITOS_ICR_LO, isr_lo); | ||
563 | 574 | ||
564 | if (unlikely((isr & ~TALITOS_ISR_CHDONE) || isr_lo)) | ||
565 | talitos_error((unsigned long)data, isr, isr_lo); | 575 | talitos_error((unsigned long)data, isr, isr_lo); |
566 | else | 576 | } else |
567 | if (likely(isr & TALITOS_ISR_CHDONE)) | 577 | if (likely(isr & TALITOS_ISR_CHDONE)) { |
578 | /* mask further done interrupts. */ | ||
579 | clrbits32(priv->reg + TALITOS_IMR, TALITOS_IMR_DONE); | ||
580 | /* done_task will unmask done interrupts at exit */ | ||
568 | tasklet_schedule(&priv->done_task); | 581 | tasklet_schedule(&priv->done_task); |
582 | } | ||
569 | 583 | ||
570 | return (isr || isr_lo) ? IRQ_HANDLED : IRQ_NONE; | 584 | return (isr || isr_lo) ? IRQ_HANDLED : IRQ_NONE; |
571 | } | 585 | } |
diff --git a/drivers/crypto/talitos.h b/drivers/crypto/talitos.h index c48a405abf70..e6b87770df03 100644 --- a/drivers/crypto/talitos.h +++ b/drivers/crypto/talitos.h | |||
@@ -37,7 +37,8 @@ | |||
37 | #define TALITOS_MCR_LO 0x1038 | 37 | #define TALITOS_MCR_LO 0x1038 |
38 | #define TALITOS_MCR_SWR 0x1 /* s/w reset */ | 38 | #define TALITOS_MCR_SWR 0x1 /* s/w reset */ |
39 | #define TALITOS_IMR 0x1008 /* interrupt mask register */ | 39 | #define TALITOS_IMR 0x1008 /* interrupt mask register */ |
40 | #define TALITOS_IMR_INIT 0x10fff /* enable channel IRQs */ | 40 | #define TALITOS_IMR_INIT 0x100ff /* enable channel IRQs */ |
41 | #define TALITOS_IMR_DONE 0x00055 /* done IRQs */ | ||
41 | #define TALITOS_IMR_LO 0x100C | 42 | #define TALITOS_IMR_LO 0x100C |
42 | #define TALITOS_IMR_LO_INIT 0x20000 /* allow RNGU error IRQs */ | 43 | #define TALITOS_IMR_LO_INIT 0x20000 /* allow RNGU error IRQs */ |
43 | #define TALITOS_ISR 0x1010 /* interrupt status register */ | 44 | #define TALITOS_ISR 0x1010 /* interrupt status register */ |