|
@@ -63,7 +63,7 @@ struct dcp {
|
|
|
struct dcp_coherent_block *coh;
|
|
|
|
|
|
struct completion completion[DCP_MAX_CHANS];
|
|
|
- struct mutex mutex[DCP_MAX_CHANS];
|
|
|
+ spinlock_t lock[DCP_MAX_CHANS];
|
|
|
struct task_struct *thread[DCP_MAX_CHANS];
|
|
|
struct crypto_queue queue[DCP_MAX_CHANS];
|
|
|
};
|
|
@@ -349,13 +349,20 @@ static int dcp_chan_thread_aes(void *data)
|
|
|
|
|
|
int ret;
|
|
|
|
|
|
- do {
|
|
|
- __set_current_state(TASK_INTERRUPTIBLE);
|
|
|
+ while (!kthread_should_stop()) {
|
|
|
+ set_current_state(TASK_INTERRUPTIBLE);
|
|
|
|
|
|
- mutex_lock(&sdcp->mutex[chan]);
|
|
|
+ spin_lock(&sdcp->lock[chan]);
|
|
|
backlog = crypto_get_backlog(&sdcp->queue[chan]);
|
|
|
arq = crypto_dequeue_request(&sdcp->queue[chan]);
|
|
|
- mutex_unlock(&sdcp->mutex[chan]);
|
|
|
+ spin_unlock(&sdcp->lock[chan]);
|
|
|
+
|
|
|
+ if (!backlog && !arq) {
|
|
|
+ schedule();
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
+ set_current_state(TASK_RUNNING);
|
|
|
|
|
|
if (backlog)
|
|
|
backlog->complete(backlog, -EINPROGRESS);
|
|
@@ -363,11 +370,8 @@ static int dcp_chan_thread_aes(void *data)
|
|
|
if (arq) {
|
|
|
ret = mxs_dcp_aes_block_crypt(arq);
|
|
|
arq->complete(arq, ret);
|
|
|
- continue;
|
|
|
}
|
|
|
-
|
|
|
- schedule();
|
|
|
- } while (!kthread_should_stop());
|
|
|
+ }
|
|
|
|
|
|
return 0;
|
|
|
}
|
|
@@ -409,9 +413,9 @@ static int mxs_dcp_aes_enqueue(struct ablkcipher_request *req, int enc, int ecb)
|
|
|
rctx->ecb = ecb;
|
|
|
actx->chan = DCP_CHAN_CRYPTO;
|
|
|
|
|
|
- mutex_lock(&sdcp->mutex[actx->chan]);
|
|
|
+ spin_lock(&sdcp->lock[actx->chan]);
|
|
|
ret = crypto_enqueue_request(&sdcp->queue[actx->chan], &req->base);
|
|
|
- mutex_unlock(&sdcp->mutex[actx->chan]);
|
|
|
+ spin_unlock(&sdcp->lock[actx->chan]);
|
|
|
|
|
|
wake_up_process(sdcp->thread[actx->chan]);
|
|
|
|
|
@@ -640,13 +644,20 @@ static int dcp_chan_thread_sha(void *data)
|
|
|
struct ahash_request *req;
|
|
|
int ret, fini;
|
|
|
|
|
|
- do {
|
|
|
- __set_current_state(TASK_INTERRUPTIBLE);
|
|
|
+ while (!kthread_should_stop()) {
|
|
|
+ set_current_state(TASK_INTERRUPTIBLE);
|
|
|
|
|
|
- mutex_lock(&sdcp->mutex[chan]);
|
|
|
+ spin_lock(&sdcp->lock[chan]);
|
|
|
backlog = crypto_get_backlog(&sdcp->queue[chan]);
|
|
|
arq = crypto_dequeue_request(&sdcp->queue[chan]);
|
|
|
- mutex_unlock(&sdcp->mutex[chan]);
|
|
|
+ spin_unlock(&sdcp->lock[chan]);
|
|
|
+
|
|
|
+ if (!backlog && !arq) {
|
|
|
+ schedule();
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
+ set_current_state(TASK_RUNNING);
|
|
|
|
|
|
if (backlog)
|
|
|
backlog->complete(backlog, -EINPROGRESS);
|
|
@@ -658,12 +669,8 @@ static int dcp_chan_thread_sha(void *data)
|
|
|
ret = dcp_sha_req_to_buf(arq);
|
|
|
fini = rctx->fini;
|
|
|
arq->complete(arq, ret);
|
|
|
- if (!fini)
|
|
|
- continue;
|
|
|
}
|
|
|
-
|
|
|
- schedule();
|
|
|
- } while (!kthread_should_stop());
|
|
|
+ }
|
|
|
|
|
|
return 0;
|
|
|
}
|
|
@@ -721,9 +728,9 @@ static int dcp_sha_update_fx(struct ahash_request *req, int fini)
|
|
|
rctx->init = 1;
|
|
|
}
|
|
|
|
|
|
- mutex_lock(&sdcp->mutex[actx->chan]);
|
|
|
+ spin_lock(&sdcp->lock[actx->chan]);
|
|
|
ret = crypto_enqueue_request(&sdcp->queue[actx->chan], &req->base);
|
|
|
- mutex_unlock(&sdcp->mutex[actx->chan]);
|
|
|
+ spin_unlock(&sdcp->lock[actx->chan]);
|
|
|
|
|
|
wake_up_process(sdcp->thread[actx->chan]);
|
|
|
mutex_unlock(&actx->mutex);
|
|
@@ -997,7 +1004,7 @@ static int mxs_dcp_probe(struct platform_device *pdev)
|
|
|
platform_set_drvdata(pdev, sdcp);
|
|
|
|
|
|
for (i = 0; i < DCP_MAX_CHANS; i++) {
|
|
|
- mutex_init(&sdcp->mutex[i]);
|
|
|
+ spin_lock_init(&sdcp->lock[i]);
|
|
|
init_completion(&sdcp->completion[i]);
|
|
|
crypto_init_queue(&sdcp->queue[i], 50);
|
|
|
}
|