Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 1af8ea86 authored by Bharat Bhushan's avatar Bharat Bhushan Committed by Herbert Xu
Browse files

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: default avatarBharat Bhushan <bharat.bhushan@freescale.com>
Acked-by: default avatarKim Phillips <kim.phillips@freescale.com>
Signed-off-by: default avatarHerbert Xu <herbert@gondor.apana.org.au>
parent 26c8aaeb
Loading
Loading
Loading
Loading
+9 −36
Original line number Original line Diff line number Diff line
@@ -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;