crypto: caam - Using alloc_coherent for caam job rings
The caam job rings (input/output job ring) are allocated using dma_map_single(). These job rings can be visualized as the ring buffers in which the jobs are en-queued/de-queued. The s/w enqueues the jobs in input job ring which h/w dequeues and after processing it copies the jobs in output job ring. Software then de-queues the job from output ring. Using dma_map/unmap_single() is not preferred way to allocate memory for this type of requirements because this adds un-necessary complexity. Example, if bounce buffer (SWIOTLB) will get used then to make any change visible in this memory to other processing unit requires dmap_unmap_single() or dma_sync_single_for_cpu/device(). The dma_unmap_single() can not be used as this will free the bounce buffer, this will require changing the job rings on running system and I seriously doubt that it will be not possible or very complex to implement. Also using dma_sync_single_for_cpu/device() will also add unnecessary complexity. The simple and preferred way is using dma_alloc_coherent() for these type of memory requirements. This resolves the Linux boot crash issue when "swiotlb=force" is set in bootargs on systems which have memory more than 4G. Signed-off-by: Bharat Bhushan <bharat.bhushan@freescale.com> Acked-by: Kim Phillips <kim.phillips@freescale.com> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
This commit is contained in:
parent
26c8aaebc1
commit
1af8ea862c
|
@ -339,10 +339,11 @@ static int caam_jr_init(struct device *dev)
|
||||||
if (error)
|
if (error)
|
||||||
return error;
|
return error;
|
||||||
|
|
||||||
jrp->inpring = kzalloc(sizeof(dma_addr_t) * JOBR_DEPTH,
|
jrp->inpring = dma_alloc_coherent(dev, sizeof(dma_addr_t) * JOBR_DEPTH,
|
||||||
GFP_KERNEL | GFP_DMA);
|
&inpbusaddr, GFP_KERNEL);
|
||||||
jrp->outring = kzalloc(sizeof(struct jr_outentry) *
|
|
||||||
JOBR_DEPTH, GFP_KERNEL | GFP_DMA);
|
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,
|
jrp->entinfo = kzalloc(sizeof(struct caam_jrentry_info) * JOBR_DEPTH,
|
||||||
GFP_KERNEL);
|
GFP_KERNEL);
|
||||||
|
@ -358,31 +359,6 @@ static int caam_jr_init(struct device *dev)
|
||||||
jrp->entinfo[i].desc_addr_dma = !0;
|
jrp->entinfo[i].desc_addr_dma = !0;
|
||||||
|
|
||||||
/* Setup rings */
|
/* Setup rings */
|
||||||
inpbusaddr = dma_map_single(dev, jrp->inpring,
|
|
||||||
sizeof(dma_addr_t) * JOBR_DEPTH,
|
|
||||||
DMA_BIDIRECTIONAL);
|
|
||||||
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_BIDIRECTIONAL);
|
|
||||||
if (dma_mapping_error(dev, outbusaddr)) {
|
|
||||||
dev_err(dev, "caam_jr_init(): can't map output ring\n");
|
|
||||||
dma_unmap_single(dev, inpbusaddr,
|
|
||||||
sizeof(dma_addr_t) * JOBR_DEPTH,
|
|
||||||
DMA_BIDIRECTIONAL);
|
|
||||||
kfree(jrp->inpring);
|
|
||||||
kfree(jrp->outring);
|
|
||||||
kfree(jrp->entinfo);
|
|
||||||
return -EIO;
|
|
||||||
}
|
|
||||||
|
|
||||||
jrp->inp_ring_write_index = 0;
|
jrp->inp_ring_write_index = 0;
|
||||||
jrp->out_ring_read_index = 0;
|
jrp->out_ring_read_index = 0;
|
||||||
jrp->head = 0;
|
jrp->head = 0;
|
||||||
|
@ -426,13 +402,10 @@ int caam_jr_shutdown(struct device *dev)
|
||||||
/* Free rings */
|
/* Free rings */
|
||||||
inpbusaddr = rd_reg64(&jrp->rregs->inpring_base);
|
inpbusaddr = rd_reg64(&jrp->rregs->inpring_base);
|
||||||
outbusaddr = rd_reg64(&jrp->rregs->outring_base);
|
outbusaddr = rd_reg64(&jrp->rregs->outring_base);
|
||||||
dma_unmap_single(dev, outbusaddr,
|
dma_free_coherent(dev, sizeof(dma_addr_t) * JOBR_DEPTH,
|
||||||
sizeof(struct jr_outentry) * JOBR_DEPTH,
|
jrp->inpring, inpbusaddr);
|
||||||
DMA_BIDIRECTIONAL);
|
dma_free_coherent(dev, sizeof(struct jr_outentry) * JOBR_DEPTH,
|
||||||
dma_unmap_single(dev, inpbusaddr, sizeof(dma_addr_t) * JOBR_DEPTH,
|
jrp->outring, outbusaddr);
|
||||||
DMA_BIDIRECTIONAL);
|
|
||||||
kfree(jrp->outring);
|
|
||||||
kfree(jrp->inpring);
|
|
||||||
kfree(jrp->entinfo);
|
kfree(jrp->entinfo);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
|
Loading…
Reference in New Issue