aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/crypto/caam/jr.c
diff options
context:
space:
mode:
authorKim Phillips <kim.phillips@freescale.com>2011-04-11 20:15:16 -0400
committerHerbert Xu <herbert@gondor.apana.org.au>2011-05-02 19:53:31 -0400
commit9620fd959fb169358f2ba349c9fd1bcd96944c28 (patch)
tree6aa26326b3bf82e8f30912a1599219f6edd41101 /drivers/crypto/caam/jr.c
parentbf362759034cf208966dff262c7d740a6b1b3edd (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>
Diffstat (limited to 'drivers/crypto/caam/jr.c')
-rw-r--r--drivers/crypto/caam/jr.c46
1 files changed, 20 insertions, 26 deletions
diff --git a/drivers/crypto/caam/jr.c b/drivers/crypto/caam/jr.c
index 68cb9af4d1a3..340fa322c0f0 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)
292 unsigned int timeout = 100000; 292 unsigned int timeout = 100000;
293 293
294 /* 294 /*
295 * FIXME: disabling IRQs here inhibits proper job completion 295 * mask interrupts since we are going to poll
296 * and error propagation 296 * for reset completion status
297 */ 297 */
298 disable_irq(jrp->irq); 298 setbits32(&jrp->rregs->rconfig_lo, JRCFG_IMSK);
299 299
300 /* initiate flush (required prior to reset) */ 300 /* initiate flush (required prior to reset) */
301 wr_reg32(&jrp->rregs->jrcommand, JRCR_RESET); 301 wr_reg32(&jrp->rregs->jrcommand, JRCR_RESET);
@@ -320,7 +320,8 @@ static int caam_reset_hw_jr(struct device *dev)
320 return -EIO; 320 return -EIO;
321 } 321 }
322 322
323 enable_irq(jrp->irq); 323 /* unmask interrupts */
324 clrbits32(&jrp->rregs->rconfig_lo, JRCFG_IMSK);
324 325
325 return 0; 326 return 0;
326} 327}
@@ -336,6 +337,21 @@ static int caam_jr_init(struct device *dev)
336 337
337 jrp = dev_get_drvdata(dev); 338 jrp = dev_get_drvdata(dev);
338 339
340 /* Connect job ring interrupt handler. */
341 for_each_possible_cpu(i)
342 tasklet_init(&jrp->irqtask[i], caam_jr_dequeue,
343 (unsigned long)dev);
344
345 error = request_irq(jrp->irq, caam_jr_interrupt, IRQF_SHARED,
346 "caam-jobr", dev);
347 if (error) {
348 dev_err(dev, "can't connect JobR %d interrupt (%d)\n",
349 jrp->ridx, jrp->irq);
350 irq_dispose_mapping(jrp->irq);
351 jrp->irq = 0;
352 return -EINVAL;
353 }
354
339 error = caam_reset_hw_jr(dev); 355 error = caam_reset_hw_jr(dev);
340 if (error) 356 if (error)
341 return error; 357 return error;
@@ -404,28 +420,6 @@ static int caam_jr_init(struct device *dev)
404 (JOBR_INTC_COUNT_THLD << JRCFG_ICDCT_SHIFT) | 420 (JOBR_INTC_COUNT_THLD << JRCFG_ICDCT_SHIFT) |
405 (JOBR_INTC_TIME_THLD << JRCFG_ICTT_SHIFT)); 421 (JOBR_INTC_TIME_THLD << JRCFG_ICTT_SHIFT));
406 422
407 /* Connect job ring interrupt handler. */
408 for_each_possible_cpu(i)
409 tasklet_init(&jrp->irqtask[i], caam_jr_dequeue,
410 (unsigned long)dev);
411
412 error = request_irq(jrp->irq, caam_jr_interrupt, 0,
413 "caam-jobr", dev);
414 if (error) {
415 dev_err(dev, "can't connect JobR %d interrupt (%d)\n",
416 jrp->ridx, jrp->irq);
417 irq_dispose_mapping(jrp->irq);
418 jrp->irq = 0;
419 dma_unmap_single(dev, inpbusaddr, sizeof(u32 *) * JOBR_DEPTH,
420 DMA_BIDIRECTIONAL);
421 dma_unmap_single(dev, outbusaddr, sizeof(u32 *) * JOBR_DEPTH,
422 DMA_BIDIRECTIONAL);
423 kfree(jrp->inpring);
424 kfree(jrp->outring);
425 kfree(jrp->entinfo);
426 return -EINVAL;
427 }
428
429 jrp->assign = JOBR_UNASSIGNED; 423 jrp->assign = JOBR_UNASSIGNED;
430 return 0; 424 return 0;
431} 425}