Commit 8043bb1a authored by Tero Kristo's avatar Tero Kristo Committed by Herbert Xu

crypto: omap-sham - convert driver logic to use sgs for data xmit

Currently, the internal buffer has been used for data transmission. Change
this so that scatterlists are used instead, and change the driver to
actually use the previously introduced helper functions for scatterlist
preparation.

This patch also removes the old buffer handling code which is no longer
needed.
Signed-off-by: default avatarTero Kristo <t-kristo@ti.com>
Signed-off-by: default avatarHerbert Xu <herbert@gondor.apana.org.au>
parent 2c5bd1ef
...@@ -116,7 +116,6 @@ ...@@ -116,7 +116,6 @@
#define FLAGS_SGS_ALLOCED 10 #define FLAGS_SGS_ALLOCED 10
/* context flags */ /* context flags */
#define FLAGS_FINUP 16 #define FLAGS_FINUP 16
#define FLAGS_SG 17
#define FLAGS_MODE_SHIFT 18 #define FLAGS_MODE_SHIFT 18
#define FLAGS_MODE_MASK (SHA_REG_MODE_ALGO_MASK << FLAGS_MODE_SHIFT) #define FLAGS_MODE_MASK (SHA_REG_MODE_ALGO_MASK << FLAGS_MODE_SHIFT)
...@@ -150,13 +149,11 @@ struct omap_sham_reqctx { ...@@ -150,13 +149,11 @@ struct omap_sham_reqctx {
size_t digcnt; size_t digcnt;
size_t bufcnt; size_t bufcnt;
size_t buflen; size_t buflen;
dma_addr_t dma_addr;
/* walk state */ /* walk state */
struct scatterlist *sg; struct scatterlist *sg;
struct scatterlist sgl[2]; struct scatterlist sgl[2];
struct scatterlist sgl_tmp; int offset; /* offset in current sg */
unsigned int offset; /* offset in current sg */
int sg_len; int sg_len;
unsigned int total; /* total request */ unsigned int total; /* total request */
...@@ -516,12 +513,14 @@ static int omap_sham_poll_irq_omap4(struct omap_sham_dev *dd) ...@@ -516,12 +513,14 @@ static int omap_sham_poll_irq_omap4(struct omap_sham_dev *dd)
SHA_REG_IRQSTATUS_INPUT_RDY); SHA_REG_IRQSTATUS_INPUT_RDY);
} }
static int omap_sham_xmit_cpu(struct omap_sham_dev *dd, const u8 *buf, static int omap_sham_xmit_cpu(struct omap_sham_dev *dd, size_t length,
size_t length, int final) int final)
{ {
struct omap_sham_reqctx *ctx = ahash_request_ctx(dd->req); struct omap_sham_reqctx *ctx = ahash_request_ctx(dd->req);
int count, len32, bs32, offset = 0; int count, len32, bs32, offset = 0;
const u32 *buffer = (const u32 *)buf; const u32 *buffer;
int mlen;
struct sg_mapping_iter mi;
dev_dbg(dd->dev, "xmit_cpu: digcnt: %d, length: %d, final: %d\n", dev_dbg(dd->dev, "xmit_cpu: digcnt: %d, length: %d, final: %d\n",
ctx->digcnt, length, final); ctx->digcnt, length, final);
...@@ -531,6 +530,7 @@ static int omap_sham_xmit_cpu(struct omap_sham_dev *dd, const u8 *buf, ...@@ -531,6 +530,7 @@ static int omap_sham_xmit_cpu(struct omap_sham_dev *dd, const u8 *buf,
/* should be non-zero before next lines to disable clocks later */ /* should be non-zero before next lines to disable clocks later */
ctx->digcnt += length; ctx->digcnt += length;
ctx->total -= length;
if (final) if (final)
set_bit(FLAGS_FINAL, &dd->flags); /* catch last interrupt */ set_bit(FLAGS_FINAL, &dd->flags); /* catch last interrupt */
...@@ -540,16 +540,35 @@ static int omap_sham_xmit_cpu(struct omap_sham_dev *dd, const u8 *buf, ...@@ -540,16 +540,35 @@ static int omap_sham_xmit_cpu(struct omap_sham_dev *dd, const u8 *buf,
len32 = DIV_ROUND_UP(length, sizeof(u32)); len32 = DIV_ROUND_UP(length, sizeof(u32));
bs32 = get_block_size(ctx) / sizeof(u32); bs32 = get_block_size(ctx) / sizeof(u32);
sg_miter_start(&mi, ctx->sg, ctx->sg_len,
SG_MITER_FROM_SG | SG_MITER_ATOMIC);
mlen = 0;
while (len32) { while (len32) {
if (dd->pdata->poll_irq(dd)) if (dd->pdata->poll_irq(dd))
return -ETIMEDOUT; return -ETIMEDOUT;
for (count = 0; count < min(len32, bs32); count++, offset++) for (count = 0; count < min(len32, bs32); count++, offset++) {
if (!mlen) {
sg_miter_next(&mi);
mlen = mi.length;
if (!mlen) {
pr_err("sg miter failure.\n");
return -EINVAL;
}
offset = 0;
buffer = mi.addr;
}
omap_sham_write(dd, SHA_REG_DIN(dd, count), omap_sham_write(dd, SHA_REG_DIN(dd, count),
buffer[offset]); buffer[offset]);
mlen -= 4;
}
len32 -= min(len32, bs32); len32 -= min(len32, bs32);
} }
sg_miter_stop(&mi);
return -EINPROGRESS; return -EINPROGRESS;
} }
...@@ -561,22 +580,27 @@ static void omap_sham_dma_callback(void *param) ...@@ -561,22 +580,27 @@ static void omap_sham_dma_callback(void *param)
tasklet_schedule(&dd->done_task); tasklet_schedule(&dd->done_task);
} }
static int omap_sham_xmit_dma(struct omap_sham_dev *dd, dma_addr_t dma_addr, static int omap_sham_xmit_dma(struct omap_sham_dev *dd, size_t length,
size_t length, int final, int is_sg) int final)
{ {
struct omap_sham_reqctx *ctx = ahash_request_ctx(dd->req); struct omap_sham_reqctx *ctx = ahash_request_ctx(dd->req);
struct dma_async_tx_descriptor *tx; struct dma_async_tx_descriptor *tx;
struct dma_slave_config cfg; struct dma_slave_config cfg;
int len32, ret, dma_min = get_block_size(ctx); int ret;
dev_dbg(dd->dev, "xmit_dma: digcnt: %d, length: %d, final: %d\n", dev_dbg(dd->dev, "xmit_dma: digcnt: %d, length: %d, final: %d\n",
ctx->digcnt, length, final); ctx->digcnt, length, final);
if (!dma_map_sg(dd->dev, ctx->sg, ctx->sg_len, DMA_TO_DEVICE)) {
dev_err(dd->dev, "dma_map_sg error\n");
return -EINVAL;
}
memset(&cfg, 0, sizeof(cfg)); memset(&cfg, 0, sizeof(cfg));
cfg.dst_addr = dd->phys_base + SHA_REG_DIN(dd, 0); cfg.dst_addr = dd->phys_base + SHA_REG_DIN(dd, 0);
cfg.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; cfg.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
cfg.dst_maxburst = dma_min / DMA_SLAVE_BUSWIDTH_4_BYTES; cfg.dst_maxburst = get_block_size(ctx) / DMA_SLAVE_BUSWIDTH_4_BYTES;
ret = dmaengine_slave_config(dd->dma_lch, &cfg); ret = dmaengine_slave_config(dd->dma_lch, &cfg);
if (ret) { if (ret) {
...@@ -584,31 +608,12 @@ static int omap_sham_xmit_dma(struct omap_sham_dev *dd, dma_addr_t dma_addr, ...@@ -584,31 +608,12 @@ static int omap_sham_xmit_dma(struct omap_sham_dev *dd, dma_addr_t dma_addr,
return ret; return ret;
} }
len32 = DIV_ROUND_UP(length, dma_min) * dma_min; tx = dmaengine_prep_slave_sg(dd->dma_lch, ctx->sg, ctx->sg_len,
DMA_MEM_TO_DEV,
if (is_sg) { DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
/*
* The SG entry passed in may not have the 'length' member
* set correctly so use a local SG entry (sgl_tmp) with the
* proper value for 'length' instead. If this is not done,
* the dmaengine may try to DMA the incorrect amount of data.
*/
sg_init_table(&ctx->sgl_tmp, 1);
sg_assign_page(&ctx->sgl_tmp, sg_page(ctx->sg));
ctx->sgl_tmp.offset = ctx->sg->offset;
sg_dma_len(&ctx->sgl_tmp) = len32;
sg_dma_address(&ctx->sgl_tmp) = sg_dma_address(ctx->sg);
tx = dmaengine_prep_slave_sg(dd->dma_lch, &ctx->sgl_tmp, 1,
DMA_MEM_TO_DEV,
DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
} else {
tx = dmaengine_prep_slave_single(dd->dma_lch, dma_addr, len32,
DMA_MEM_TO_DEV, DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
}
if (!tx) { if (!tx) {
dev_err(dd->dev, "prep_slave_sg/single() failed\n"); dev_err(dd->dev, "prep_slave_sg failed\n");
return -EINVAL; return -EINVAL;
} }
...@@ -618,6 +623,7 @@ static int omap_sham_xmit_dma(struct omap_sham_dev *dd, dma_addr_t dma_addr, ...@@ -618,6 +623,7 @@ static int omap_sham_xmit_dma(struct omap_sham_dev *dd, dma_addr_t dma_addr,
dd->pdata->write_ctrl(dd, length, final, 1); dd->pdata->write_ctrl(dd, length, final, 1);
ctx->digcnt += length; ctx->digcnt += length;
ctx->total -= length;
if (final) if (final)
set_bit(FLAGS_FINAL, &dd->flags); /* catch last interrupt */ set_bit(FLAGS_FINAL, &dd->flags); /* catch last interrupt */
...@@ -886,208 +892,13 @@ static int omap_sham_prepare_request(struct ahash_request *req, bool update) ...@@ -886,208 +892,13 @@ static int omap_sham_prepare_request(struct ahash_request *req, bool update)
return 0; return 0;
} }
static size_t omap_sham_append_buffer(struct omap_sham_reqctx *ctx,
const u8 *data, size_t length)
{
size_t count = min(length, ctx->buflen - ctx->bufcnt);
count = min(count, ctx->total);
if (count <= 0)
return 0;
memcpy(ctx->buffer + ctx->bufcnt, data, count);
ctx->bufcnt += count;
return count;
}
static size_t omap_sham_append_sg(struct omap_sham_reqctx *ctx)
{
size_t count;
const u8 *vaddr;
while (ctx->sg) {
vaddr = kmap_atomic(sg_page(ctx->sg));
vaddr += ctx->sg->offset;
count = omap_sham_append_buffer(ctx,
vaddr + ctx->offset,
ctx->sg->length - ctx->offset);
kunmap_atomic((void *)vaddr);
if (!count)
break;
ctx->offset += count;
ctx->total -= count;
if (ctx->offset == ctx->sg->length) {
ctx->sg = sg_next(ctx->sg);
if (ctx->sg)
ctx->offset = 0;
else
ctx->total = 0;
}
}
return 0;
}
static int omap_sham_xmit_dma_map(struct omap_sham_dev *dd,
struct omap_sham_reqctx *ctx,
size_t length, int final)
{
int ret;
ctx->dma_addr = dma_map_single(dd->dev, ctx->buffer, ctx->buflen,
DMA_TO_DEVICE);
if (dma_mapping_error(dd->dev, ctx->dma_addr)) {
dev_err(dd->dev, "dma %u bytes error\n", ctx->buflen);
return -EINVAL;
}
ctx->flags &= ~BIT(FLAGS_SG);
ret = omap_sham_xmit_dma(dd, ctx->dma_addr, length, final, 0);
if (ret != -EINPROGRESS)
dma_unmap_single(dd->dev, ctx->dma_addr, ctx->buflen,
DMA_TO_DEVICE);
return ret;
}
static int omap_sham_update_dma_slow(struct omap_sham_dev *dd)
{
struct omap_sham_reqctx *ctx = ahash_request_ctx(dd->req);
unsigned int final;
size_t count;
omap_sham_append_sg(ctx);
final = (ctx->flags & BIT(FLAGS_FINUP)) && !ctx->total;
dev_dbg(dd->dev, "slow: bufcnt: %u, digcnt: %d, final: %d\n",
ctx->bufcnt, ctx->digcnt, final);
if (final || (ctx->bufcnt == ctx->buflen && ctx->total)) {
count = ctx->bufcnt;
ctx->bufcnt = 0;
return omap_sham_xmit_dma_map(dd, ctx, count, final);
}
return 0;
}
/* Start address alignment */
#define SG_AA(sg) (IS_ALIGNED(sg->offset, sizeof(u32)))
/* SHA1 block size alignment */
#define SG_SA(sg, bs) (IS_ALIGNED(sg->length, bs))
static int omap_sham_update_dma_start(struct omap_sham_dev *dd)
{
struct omap_sham_reqctx *ctx = ahash_request_ctx(dd->req);
unsigned int length, final, tail;
struct scatterlist *sg;
int ret, bs;
if (!ctx->total)
return 0;
if (ctx->bufcnt || ctx->offset)
return omap_sham_update_dma_slow(dd);
/*
* Don't use the sg interface when the transfer size is less
* than the number of elements in a DMA frame. Otherwise,
* the dmaengine infrastructure will calculate that it needs
* to transfer 0 frames which ultimately fails.
*/
if (ctx->total < get_block_size(ctx))
return omap_sham_update_dma_slow(dd);
dev_dbg(dd->dev, "fast: digcnt: %d, bufcnt: %u, total: %u\n",
ctx->digcnt, ctx->bufcnt, ctx->total);
sg = ctx->sg;
bs = get_block_size(ctx);
if (!SG_AA(sg))
return omap_sham_update_dma_slow(dd);
if (!sg_is_last(sg) && !SG_SA(sg, bs))
/* size is not BLOCK_SIZE aligned */
return omap_sham_update_dma_slow(dd);
length = min(ctx->total, sg->length);
if (sg_is_last(sg)) {
if (!(ctx->flags & BIT(FLAGS_FINUP))) {
/* not last sg must be BLOCK_SIZE aligned */
tail = length & (bs - 1);
/* without finup() we need one block to close hash */
if (!tail)
tail = bs;
length -= tail;
}
}
if (!dma_map_sg(dd->dev, ctx->sg, 1, DMA_TO_DEVICE)) {
dev_err(dd->dev, "dma_map_sg error\n");
return -EINVAL;
}
ctx->flags |= BIT(FLAGS_SG);
ctx->total -= length;
ctx->offset = length; /* offset where to start slow */
final = (ctx->flags & BIT(FLAGS_FINUP)) && !ctx->total;
ret = omap_sham_xmit_dma(dd, sg_dma_address(ctx->sg), length, final, 1);
if (ret != -EINPROGRESS)
dma_unmap_sg(dd->dev, ctx->sg, 1, DMA_TO_DEVICE);
return ret;
}
static int omap_sham_update_cpu(struct omap_sham_dev *dd)
{
struct omap_sham_reqctx *ctx = ahash_request_ctx(dd->req);
int bufcnt, final;
if (!ctx->total)
return 0;
omap_sham_append_sg(ctx);
final = (ctx->flags & BIT(FLAGS_FINUP)) && !ctx->total;
dev_dbg(dd->dev, "cpu: bufcnt: %u, digcnt: %d, final: %d\n",
ctx->bufcnt, ctx->digcnt, final);
if (final || (ctx->bufcnt == ctx->buflen && ctx->total)) {
bufcnt = ctx->bufcnt;
ctx->bufcnt = 0;
return omap_sham_xmit_cpu(dd, ctx->buffer, bufcnt, final);
}
return 0;
}
static int omap_sham_update_dma_stop(struct omap_sham_dev *dd) static int omap_sham_update_dma_stop(struct omap_sham_dev *dd)
{ {
struct omap_sham_reqctx *ctx = ahash_request_ctx(dd->req); struct omap_sham_reqctx *ctx = ahash_request_ctx(dd->req);
dma_unmap_sg(dd->dev, ctx->sg, ctx->sg_len, DMA_TO_DEVICE);
if (ctx->flags & BIT(FLAGS_SG)) { clear_bit(FLAGS_DMA_ACTIVE, &dd->flags);
dma_unmap_sg(dd->dev, ctx->sg, 1, DMA_TO_DEVICE);
if (ctx->sg->length == ctx->offset) {
ctx->sg = sg_next(ctx->sg);
if (ctx->sg)
ctx->offset = 0;
}
} else {
dma_unmap_single(dd->dev, ctx->dma_addr, ctx->buflen,
DMA_TO_DEVICE);
}
return 0; return 0;
} }
...@@ -1148,6 +959,8 @@ static int omap_sham_init(struct ahash_request *req) ...@@ -1148,6 +959,8 @@ static int omap_sham_init(struct ahash_request *req)
ctx->bufcnt = 0; ctx->bufcnt = 0;
ctx->digcnt = 0; ctx->digcnt = 0;
ctx->total = 0;
ctx->offset = 0;
ctx->buflen = BUFLEN; ctx->buflen = BUFLEN;
if (tctx->flags & BIT(FLAGS_HMAC)) { if (tctx->flags & BIT(FLAGS_HMAC)) {
...@@ -1170,14 +983,19 @@ static int omap_sham_update_req(struct omap_sham_dev *dd) ...@@ -1170,14 +983,19 @@ static int omap_sham_update_req(struct omap_sham_dev *dd)
struct ahash_request *req = dd->req; struct ahash_request *req = dd->req;
struct omap_sham_reqctx *ctx = ahash_request_ctx(req); struct omap_sham_reqctx *ctx = ahash_request_ctx(req);
int err; int err;
bool final = ctx->flags & BIT(FLAGS_FINUP);
dev_dbg(dd->dev, "update_req: total: %u, digcnt: %d, finup: %d\n", dev_dbg(dd->dev, "update_req: total: %u, digcnt: %d, finup: %d\n",
ctx->total, ctx->digcnt, (ctx->flags & BIT(FLAGS_FINUP)) != 0); ctx->total, ctx->digcnt, (ctx->flags & BIT(FLAGS_FINUP)) != 0);
if (ctx->total < get_block_size(ctx) ||
ctx->total < OMAP_SHA_DMA_THRESHOLD)
ctx->flags |= BIT(FLAGS_CPU);
if (ctx->flags & BIT(FLAGS_CPU)) if (ctx->flags & BIT(FLAGS_CPU))
err = omap_sham_update_cpu(dd); err = omap_sham_xmit_cpu(dd, ctx->total, final);
else else
err = omap_sham_update_dma_start(dd); err = omap_sham_xmit_dma(dd, ctx->total, final);
/* wait for dma completion before can take more data */ /* wait for dma completion before can take more data */
dev_dbg(dd->dev, "update: err: %d, digcnt: %d\n", err, ctx->digcnt); dev_dbg(dd->dev, "update: err: %d, digcnt: %d\n", err, ctx->digcnt);
...@@ -1191,7 +1009,7 @@ static int omap_sham_final_req(struct omap_sham_dev *dd) ...@@ -1191,7 +1009,7 @@ static int omap_sham_final_req(struct omap_sham_dev *dd)
struct omap_sham_reqctx *ctx = ahash_request_ctx(req); struct omap_sham_reqctx *ctx = ahash_request_ctx(req);
int err = 0, use_dma = 1; int err = 0, use_dma = 1;
if ((ctx->bufcnt <= get_block_size(ctx)) || dd->polling_mode) if ((ctx->total <= get_block_size(ctx)) || dd->polling_mode)
/* /*
* faster to handle last block with cpu or * faster to handle last block with cpu or
* use cpu when dma is not present. * use cpu when dma is not present.
...@@ -1199,9 +1017,9 @@ static int omap_sham_final_req(struct omap_sham_dev *dd) ...@@ -1199,9 +1017,9 @@ static int omap_sham_final_req(struct omap_sham_dev *dd)
use_dma = 0; use_dma = 0;
if (use_dma) if (use_dma)
err = omap_sham_xmit_dma_map(dd, ctx, ctx->bufcnt, 1); err = omap_sham_xmit_dma(dd, ctx->total, 1);
else else
err = omap_sham_xmit_cpu(dd, ctx->buffer, ctx->bufcnt, 1); err = omap_sham_xmit_cpu(dd, ctx->total, 1);
ctx->bufcnt = 0; ctx->bufcnt = 0;
...@@ -1249,6 +1067,17 @@ static void omap_sham_finish_req(struct ahash_request *req, int err) ...@@ -1249,6 +1067,17 @@ static void omap_sham_finish_req(struct ahash_request *req, int err)
struct omap_sham_reqctx *ctx = ahash_request_ctx(req); struct omap_sham_reqctx *ctx = ahash_request_ctx(req);
struct omap_sham_dev *dd = ctx->dd; struct omap_sham_dev *dd = ctx->dd;
if (test_bit(FLAGS_SGS_COPIED, &dd->flags))
free_pages((unsigned long)sg_virt(ctx->sg),
get_order(ctx->sg->length));
if (test_bit(FLAGS_SGS_ALLOCED, &dd->flags))
kfree(ctx->sg);
ctx->sg = NULL;
dd->flags &= ~(BIT(FLAGS_SGS_ALLOCED) | BIT(FLAGS_SGS_COPIED));
if (!err) { if (!err) {
dd->pdata->copy_hash(req, 1); dd->pdata->copy_hash(req, 1);
if (test_bit(FLAGS_FINAL, &dd->flags)) if (test_bit(FLAGS_FINAL, &dd->flags))
...@@ -1300,7 +1129,7 @@ static int omap_sham_handle_queue(struct omap_sham_dev *dd, ...@@ -1300,7 +1129,7 @@ static int omap_sham_handle_queue(struct omap_sham_dev *dd,
dd->req = req; dd->req = req;
ctx = ahash_request_ctx(req); ctx = ahash_request_ctx(req);
err = omap_sham_prepare_request(NULL, ctx->op == OP_UPDATE); err = omap_sham_prepare_request(req, ctx->op == OP_UPDATE);
if (err) if (err)
goto err1; goto err1;
...@@ -1356,34 +1185,15 @@ static int omap_sham_update(struct ahash_request *req) ...@@ -1356,34 +1185,15 @@ static int omap_sham_update(struct ahash_request *req)
{ {
struct omap_sham_reqctx *ctx = ahash_request_ctx(req); struct omap_sham_reqctx *ctx = ahash_request_ctx(req);
struct omap_sham_dev *dd = ctx->dd; struct omap_sham_dev *dd = ctx->dd;
int bs = get_block_size(ctx);
if (!req->nbytes) if (!req->nbytes)
return 0; return 0;
ctx->total = req->nbytes; if (ctx->total + req->nbytes < ctx->buflen) {
ctx->sg = req->src; scatterwalk_map_and_copy(ctx->buffer + ctx->bufcnt, req->src,
ctx->offset = 0; 0, req->nbytes, 0);
ctx->bufcnt += req->nbytes;
if (ctx->flags & BIT(FLAGS_FINUP)) { ctx->total += req->nbytes;
if ((ctx->digcnt + ctx->bufcnt + ctx->total) < 240) {
/*
* OMAP HW accel works only with buffers >= 9
* will switch to bypass in final()
* final has the same request and data
*/
omap_sham_append_sg(ctx);
return 0;
} else if ((ctx->bufcnt + ctx->total <= bs) ||
dd->polling_mode) {
/*
* faster to use CPU for short transfers or
* use cpu when dma is not present.
*/
ctx->flags |= BIT(FLAGS_CPU);
}
} else if (ctx->bufcnt + ctx->total < ctx->buflen) {
omap_sham_append_sg(ctx);
return 0; return 0;
} }
...@@ -1917,12 +1727,8 @@ static void omap_sham_done_task(unsigned long data) ...@@ -1917,12 +1727,8 @@ static void omap_sham_done_task(unsigned long data)
} }
if (test_bit(FLAGS_CPU, &dd->flags)) { if (test_bit(FLAGS_CPU, &dd->flags)) {
if (test_and_clear_bit(FLAGS_OUTPUT_READY, &dd->flags)) { if (test_and_clear_bit(FLAGS_OUTPUT_READY, &dd->flags))
/* hash or semi-hash ready */ goto finish;
err = omap_sham_update_cpu(dd);
if (err != -EINPROGRESS)
goto finish;
}
} else if (test_bit(FLAGS_DMA_READY, &dd->flags)) { } else if (test_bit(FLAGS_DMA_READY, &dd->flags)) {
if (test_and_clear_bit(FLAGS_DMA_ACTIVE, &dd->flags)) { if (test_and_clear_bit(FLAGS_DMA_ACTIVE, &dd->flags)) {
omap_sham_update_dma_stop(dd); omap_sham_update_dma_stop(dd);
...@@ -1934,8 +1740,6 @@ static void omap_sham_done_task(unsigned long data) ...@@ -1934,8 +1740,6 @@ static void omap_sham_done_task(unsigned long data)
if (test_and_clear_bit(FLAGS_OUTPUT_READY, &dd->flags)) { if (test_and_clear_bit(FLAGS_OUTPUT_READY, &dd->flags)) {
/* hash or semi-hash ready */ /* hash or semi-hash ready */
clear_bit(FLAGS_DMA_READY, &dd->flags); clear_bit(FLAGS_DMA_READY, &dd->flags);
err = omap_sham_update_dma_start(dd);
if (err != -EINPROGRESS)
goto finish; goto finish;
} }
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment