diff options
author | Bharat Bhushan <Bharat.Bhushan@freescale.com> | 2012-07-10 23:06:10 -0400 |
---|---|---|
committer | Herbert Xu <herbert@gondor.apana.org.au> | 2012-07-10 23:06:10 -0400 |
commit | 1af8ea862c9a9a6d5dc100850036cc7a641bb242 (patch) | |
tree | 6c17ecaad399d4a5ce1a12f17020a72e17259dc1 /drivers/crypto | |
parent | 26c8aaebc188b539a0a9077350009a059464097d (diff) |
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>
Diffstat (limited to 'drivers/crypto')
-rw-r--r-- | drivers/crypto/caam/jr.c | 45 |
1 files changed, 9 insertions, 36 deletions
diff --git a/drivers/crypto/caam/jr.c b/drivers/crypto/caam/jr.c index 7074a1a29e8b..53c8c51d5881 100644 --- a/drivers/crypto/caam/jr.c +++ b/drivers/crypto/caam/jr.c | |||
@@ -339,10 +339,11 @@ static int caam_jr_init(struct device *dev) | |||
339 | if (error) | 339 | if (error) |
340 | return error; | 340 | return error; |
341 | 341 | ||
342 | jrp->inpring = kzalloc(sizeof(dma_addr_t) * JOBR_DEPTH, | 342 | jrp->inpring = dma_alloc_coherent(dev, sizeof(dma_addr_t) * JOBR_DEPTH, |
343 | GFP_KERNEL | GFP_DMA); | 343 | &inpbusaddr, GFP_KERNEL); |
344 | jrp->outring = kzalloc(sizeof(struct jr_outentry) * | 344 | |
345 | JOBR_DEPTH, GFP_KERNEL | GFP_DMA); | 345 | jrp->outring = dma_alloc_coherent(dev, sizeof(struct jr_outentry) * |
346 | JOBR_DEPTH, &outbusaddr, GFP_KERNEL); | ||
346 | 347 | ||
347 | jrp->entinfo = kzalloc(sizeof(struct caam_jrentry_info) * JOBR_DEPTH, | 348 | jrp->entinfo = kzalloc(sizeof(struct caam_jrentry_info) * JOBR_DEPTH, |
348 | GFP_KERNEL); | 349 | GFP_KERNEL); |
@@ -358,31 +359,6 @@ static int caam_jr_init(struct device *dev) | |||
358 | jrp->entinfo[i].desc_addr_dma = !0; | 359 | jrp->entinfo[i].desc_addr_dma = !0; |
359 | 360 | ||
360 | /* Setup rings */ | 361 | /* Setup rings */ |
361 | inpbusaddr = dma_map_single(dev, jrp->inpring, | ||
362 | sizeof(dma_addr_t) * JOBR_DEPTH, | ||
363 | DMA_BIDIRECTIONAL); | ||
364 | if (dma_mapping_error(dev, inpbusaddr)) { | ||
365 | dev_err(dev, "caam_jr_init(): can't map input ring\n"); | ||
366 | kfree(jrp->inpring); | ||
367 | kfree(jrp->outring); | ||
368 | kfree(jrp->entinfo); | ||
369 | return -EIO; | ||
370 | } | ||
371 | |||
372 | outbusaddr = dma_map_single(dev, jrp->outring, | ||
373 | sizeof(struct jr_outentry) * JOBR_DEPTH, | ||
374 | DMA_BIDIRECTIONAL); | ||
375 | if (dma_mapping_error(dev, outbusaddr)) { | ||
376 | dev_err(dev, "caam_jr_init(): can't map output ring\n"); | ||
377 | dma_unmap_single(dev, inpbusaddr, | ||
378 | sizeof(dma_addr_t) * JOBR_DEPTH, | ||
379 | DMA_BIDIRECTIONAL); | ||
380 | kfree(jrp->inpring); | ||
381 | kfree(jrp->outring); | ||
382 | kfree(jrp->entinfo); | ||
383 | return -EIO; | ||
384 | } | ||
385 | |||
386 | jrp->inp_ring_write_index = 0; | 362 | jrp->inp_ring_write_index = 0; |
387 | jrp->out_ring_read_index = 0; | 363 | jrp->out_ring_read_index = 0; |
388 | jrp->head = 0; | 364 | jrp->head = 0; |
@@ -426,13 +402,10 @@ int caam_jr_shutdown(struct device *dev) | |||
426 | /* Free rings */ | 402 | /* Free rings */ |
427 | inpbusaddr = rd_reg64(&jrp->rregs->inpring_base); | 403 | inpbusaddr = rd_reg64(&jrp->rregs->inpring_base); |
428 | outbusaddr = rd_reg64(&jrp->rregs->outring_base); | 404 | outbusaddr = rd_reg64(&jrp->rregs->outring_base); |
429 | dma_unmap_single(dev, outbusaddr, | 405 | dma_free_coherent(dev, sizeof(dma_addr_t) * JOBR_DEPTH, |
430 | sizeof(struct jr_outentry) * JOBR_DEPTH, | 406 | jrp->inpring, inpbusaddr); |
431 | DMA_BIDIRECTIONAL); | 407 | dma_free_coherent(dev, sizeof(struct jr_outentry) * JOBR_DEPTH, |
432 | dma_unmap_single(dev, inpbusaddr, sizeof(dma_addr_t) * JOBR_DEPTH, | 408 | jrp->outring, outbusaddr); |
433 | DMA_BIDIRECTIONAL); | ||
434 | kfree(jrp->outring); | ||
435 | kfree(jrp->inpring); | ||
436 | kfree(jrp->entinfo); | 409 | kfree(jrp->entinfo); |
437 | 410 | ||
438 | return ret; | 411 | return ret; |