diff options
author | Kim Phillips <kim.phillips@freescale.com> | 2011-04-11 19:15:16 -0500 |
---|---|---|
committer | Herbert Xu <herbert@gondor.apana.org.au> | 2011-05-03 09:53:31 +1000 |
commit | 9620fd959fb169358f2ba349c9fd1bcd96944c28 (patch) | |
tree | 6aa26326b3bf82e8f30912a1599219f6edd41101 | |
parent | bf362759034cf208966dff262c7d740a6b1b3edd (diff) |
crypto: caam - handle interrupt lines shared across rings
- add IRQF_SHARED to request_irq flags to support parts such as
the p1023 that has one IRQ line per couple of rings.
- resetting a job ring triggers an interrupt, so move request_irq
prior to jr_reset to avoid 'got IRQ but nobody cared' messages.
- disable IRQs in h/w to avoid contention between reset and
interrupt status
- delete invalid comment - if there were incomplete jobs,
module would be in use, preventing an unload.
Signed-off-by: Kim Phillips <kim.phillips@freescale.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
-rw-r--r-- | drivers/crypto/caam/jr.c | 46 |
1 files changed, 20 insertions, 26 deletions
diff --git a/drivers/crypto/caam/jr.c b/drivers/crypto/caam/jr.c index 68cb9af4d1a..340fa322c0f 100644 --- a/drivers/crypto/caam/jr.c +++ b/drivers/crypto/caam/jr.c @@ -292,10 +292,10 @@ static int caam_reset_hw_jr(struct device *dev) unsigned int timeout = 100000; /* - * FIXME: disabling IRQs here inhibits proper job completion - * and error propagation + * mask interrupts since we are going to poll + * for reset completion status */ - disable_irq(jrp->irq); + setbits32(&jrp->rregs->rconfig_lo, JRCFG_IMSK); /* initiate flush (required prior to reset) */ wr_reg32(&jrp->rregs->jrcommand, JRCR_RESET); @@ -320,7 +320,8 @@ static int caam_reset_hw_jr(struct device *dev) return -EIO; } - enable_irq(jrp->irq); + /* unmask interrupts */ + clrbits32(&jrp->rregs->rconfig_lo, JRCFG_IMSK); return 0; } @@ -336,6 +337,21 @@ static int caam_jr_init(struct device *dev) jrp = dev_get_drvdata(dev); + /* Connect job ring interrupt handler. */ + for_each_possible_cpu(i) + tasklet_init(&jrp->irqtask[i], caam_jr_dequeue, + (unsigned long)dev); + + error = request_irq(jrp->irq, caam_jr_interrupt, IRQF_SHARED, + "caam-jobr", dev); + if (error) { + dev_err(dev, "can't connect JobR %d interrupt (%d)\n", + jrp->ridx, jrp->irq); + irq_dispose_mapping(jrp->irq); + jrp->irq = 0; + return -EINVAL; + } + error = caam_reset_hw_jr(dev); if (error) return error; @@ -404,28 +420,6 @@ static int caam_jr_init(struct device *dev) (JOBR_INTC_COUNT_THLD << JRCFG_ICDCT_SHIFT) | (JOBR_INTC_TIME_THLD << JRCFG_ICTT_SHIFT)); - /* Connect job ring interrupt handler. */ - for_each_possible_cpu(i) - tasklet_init(&jrp->irqtask[i], caam_jr_dequeue, - (unsigned long)dev); - - error = request_irq(jrp->irq, caam_jr_interrupt, 0, - "caam-jobr", dev); - if (error) { - dev_err(dev, "can't connect JobR %d interrupt (%d)\n", - jrp->ridx, jrp->irq); - irq_dispose_mapping(jrp->irq); - jrp->irq = 0; - dma_unmap_single(dev, inpbusaddr, sizeof(u32 *) * JOBR_DEPTH, - DMA_BIDIRECTIONAL); - dma_unmap_single(dev, outbusaddr, sizeof(u32 *) * JOBR_DEPTH, - DMA_BIDIRECTIONAL); - kfree(jrp->inpring); - kfree(jrp->outring); - kfree(jrp->entinfo); - return -EINVAL; - } - jrp->assign = JOBR_UNASSIGNED; return 0; } |