/* * Init JobR independent of platform property detection */ static int caam_jr_init(struct device *dev) { struct caam_drv_private_jr *jrp; dma_addr_t inpbusaddr, outbusaddr; int i, error; 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-jr", 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; jrp->inpring = kzalloc(sizeof(dma_addr_t) * JOBR_DEPTH, GFP_KERNEL | GFP_DMA); jrp->outring = kzalloc(sizeof(struct jr_outentry) * JOBR_DEPTH, GFP_KERNEL | GFP_DMA); jrp->entinfo = kzalloc(sizeof(struct caam_jrentry_info) * JOBR_DEPTH, GFP_KERNEL); if ((jrp->inpring == NULL) || (jrp->outring == NULL) || (jrp->entinfo == NULL)) { dev_err(dev, "can't allocate job rings for %d\n", jrp->ridx); return -ENOMEM; } for (i = 0; i < JOBR_DEPTH; i++) jrp->entinfo[i].desc_addr_dma = !0; /* Setup rings */ inpbusaddr = dma_map_single(dev, jrp->inpring, sizeof(u32 *) * JOBR_DEPTH, DMA_TO_DEVICE); if (dma_mapping_error(dev, inpbusaddr)) { dev_err(dev, "caam_jr_init(): can't map input ring\n"); kfree(jrp->inpring); kfree(jrp->outring); kfree(jrp->entinfo); return -EIO; } outbusaddr = dma_map_single(dev, jrp->outring, sizeof(struct jr_outentry) * JOBR_DEPTH, DMA_FROM_DEVICE); if (dma_mapping_error(dev, outbusaddr)) { dev_err(dev, "caam_jr_init(): can't map output ring\n"); dma_unmap_single(dev, inpbusaddr, sizeof(u32 *) * JOBR_DEPTH, DMA_TO_DEVICE); kfree(jrp->inpring); kfree(jrp->outring); kfree(jrp->entinfo); return -EIO; } jrp->inp_ring_write_index = 0; jrp->out_ring_read_index = 0; jrp->head = 0; jrp->tail = 0; wr_reg64(&jrp->rregs->inpring_base, inpbusaddr); wr_reg64(&jrp->rregs->outring_base, outbusaddr); wr_reg32(&jrp->rregs->inpring_size, JOBR_DEPTH); wr_reg32(&jrp->rregs->outring_size, JOBR_DEPTH); jrp->ringsize = JOBR_DEPTH; spin_lock_init(&jrp->inplock); spin_lock_init(&jrp->outlock); /* Select interrupt coalescing parameters */ setbits32(&jrp->rregs->rconfig_lo, JOBR_INTC | (JOBR_INTC_COUNT_THLD << JRCFG_ICDCT_SHIFT) | (JOBR_INTC_TIME_THLD << JRCFG_ICTT_SHIFT)); jrp->assign = JOBR_UNASSIGNED; return 0; }
/* * Init JobR independent of platform property detection */ static int caam_jr_init(struct device *dev) { struct caam_drv_private_jr *jrp; dma_addr_t inpbusaddr, outbusaddr; int i, error; jrp = dev_get_drvdata(dev); tasklet_init(&jrp->irqtask, caam_jr_dequeue, (unsigned long)dev); /* Connect job ring interrupt handler. */ 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; jrp->inpring = dma_alloc_coherent(dev, sizeof(dma_addr_t) * JOBR_DEPTH, &inpbusaddr, GFP_KERNEL); jrp->outring = dma_alloc_coherent(dev, sizeof(struct jr_outentry) * JOBR_DEPTH, &outbusaddr, GFP_KERNEL); jrp->entinfo = kzalloc(sizeof(struct caam_jrentry_info) * JOBR_DEPTH, GFP_KERNEL); if ((jrp->inpring == NULL) || (jrp->outring == NULL) || (jrp->entinfo == NULL)) { dev_err(dev, "can't allocate job rings for %d\n", jrp->ridx); return -ENOMEM; } for (i = 0; i < JOBR_DEPTH; i++) jrp->entinfo[i].desc_addr_dma = !0; /* Setup rings */ jrp->inp_ring_write_index = 0; jrp->out_ring_read_index = 0; jrp->head = 0; jrp->tail = 0; wr_reg64(&jrp->rregs->inpring_base, inpbusaddr); wr_reg64(&jrp->rregs->outring_base, outbusaddr); wr_reg32(&jrp->rregs->inpring_size, JOBR_DEPTH); wr_reg32(&jrp->rregs->outring_size, JOBR_DEPTH); jrp->ringsize = JOBR_DEPTH; spin_lock_init(&jrp->inplock); spin_lock_init(&jrp->outlock); /* Select interrupt coalescing parameters */ setbits32(&jrp->rregs->rconfig_lo, JOBR_INTC | (JOBR_INTC_COUNT_THLD << JRCFG_ICDCT_SHIFT) | (JOBR_INTC_TIME_THLD << JRCFG_ICTT_SHIFT)); return 0; }