Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Kim Phillips and committed by
Herbert Xu
9620fd95 bf362759

+20 -26
+20 -26
drivers/crypto/caam/jr.c
··· 292 292 unsigned int timeout = 100000; 293 293 294 294 /* 295 - * FIXME: disabling IRQs here inhibits proper job completion 296 - * and error propagation 295 + * mask interrupts since we are going to poll 296 + * for reset completion status 297 297 */ 298 - disable_irq(jrp->irq); 298 + setbits32(&jrp->rregs->rconfig_lo, JRCFG_IMSK); 299 299 300 300 /* initiate flush (required prior to reset) */ 301 301 wr_reg32(&jrp->rregs->jrcommand, JRCR_RESET); ··· 320 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 326 return 0; 326 327 } ··· 336 335 int i, error; 337 336 338 337 jrp = dev_get_drvdata(dev); 338 + 339 + /* Connect job ring interrupt handler. */ 340 + for_each_possible_cpu(i) 341 + tasklet_init(&jrp->irqtask[i], caam_jr_dequeue, 342 + (unsigned long)dev); 343 + 344 + error = request_irq(jrp->irq, caam_jr_interrupt, IRQF_SHARED, 345 + "caam-jobr", dev); 346 + if (error) { 347 + dev_err(dev, "can't connect JobR %d interrupt (%d)\n", 348 + jrp->ridx, jrp->irq); 349 + irq_dispose_mapping(jrp->irq); 350 + jrp->irq = 0; 351 + return -EINVAL; 352 + } 339 353 340 354 error = caam_reset_hw_jr(dev); 341 355 if (error) ··· 419 403 setbits32(&jrp->rregs->rconfig_lo, JOBR_INTC | 420 404 (JOBR_INTC_COUNT_THLD << JRCFG_ICDCT_SHIFT) | 421 405 (JOBR_INTC_TIME_THLD << JRCFG_ICTT_SHIFT)); 422 - 423 - /* Connect job ring interrupt handler. */ 424 - for_each_possible_cpu(i) 425 - tasklet_init(&jrp->irqtask[i], caam_jr_dequeue, 426 - (unsigned long)dev); 427 - 428 - error = request_irq(jrp->irq, caam_jr_interrupt, 0, 429 - "caam-jobr", dev); 430 - if (error) { 431 - dev_err(dev, "can't connect JobR %d interrupt (%d)\n", 432 - jrp->ridx, jrp->irq); 433 - irq_dispose_mapping(jrp->irq); 434 - jrp->irq = 0; 435 - dma_unmap_single(dev, inpbusaddr, sizeof(u32 *) * JOBR_DEPTH, 436 - DMA_BIDIRECTIONAL); 437 - dma_unmap_single(dev, outbusaddr, sizeof(u32 *) * JOBR_DEPTH, 438 - DMA_BIDIRECTIONAL); 439 - kfree(jrp->inpring); 440 - kfree(jrp->outring); 441 - kfree(jrp->entinfo); 442 - return -EINVAL; 443 - } 444 406 445 407 jrp->assign = JOBR_UNASSIGNED; 446 408 return 0;