Skip to content

Commit 5a7801f

Browse files
zainwangrockchipsherbertx
authored andcommitted
crypto: rockchip - Don't dequeue the request when device is busy
The device can only process one request at a time. So if multiple requests came at the same time, we can enqueue them first, and dequeue them one by one when the device is idle. Signed-off-by: zain wang <[email protected]> Signed-off-by: Herbert Xu <[email protected]>
1 parent baf5b75 commit 5a7801f

File tree

4 files changed

+160
-148
lines changed

4 files changed

+160
-148
lines changed

drivers/crypto/rockchip/rk3288_crypto.c

Lines changed: 43 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -184,29 +184,67 @@ static irqreturn_t rk_crypto_irq_handle(int irq, void *dev_id)
184184
return IRQ_HANDLED;
185185
}
186186

187+
static int rk_crypto_enqueue(struct rk_crypto_info *dev,
188+
struct crypto_async_request *async_req)
189+
{
190+
unsigned long flags;
191+
int ret;
192+
193+
spin_lock_irqsave(&dev->lock, flags);
194+
ret = crypto_enqueue_request(&dev->queue, async_req);
195+
if (dev->busy) {
196+
spin_unlock_irqrestore(&dev->lock, flags);
197+
return ret;
198+
}
199+
dev->busy = true;
200+
spin_unlock_irqrestore(&dev->lock, flags);
201+
tasklet_schedule(&dev->queue_task);
202+
203+
return ret;
204+
}
205+
187206
static void rk_crypto_queue_task_cb(unsigned long data)
188207
{
189208
struct rk_crypto_info *dev = (struct rk_crypto_info *)data;
209+
struct crypto_async_request *async_req, *backlog;
210+
unsigned long flags;
190211
int err = 0;
191212

192213
dev->err = 0;
214+
spin_lock_irqsave(&dev->lock, flags);
215+
backlog = crypto_get_backlog(&dev->queue);
216+
async_req = crypto_dequeue_request(&dev->queue);
217+
218+
if (!async_req) {
219+
dev->busy = false;
220+
spin_unlock_irqrestore(&dev->lock, flags);
221+
return;
222+
}
223+
spin_unlock_irqrestore(&dev->lock, flags);
224+
225+
if (backlog) {
226+
backlog->complete(backlog, -EINPROGRESS);
227+
backlog = NULL;
228+
}
229+
230+
dev->async_req = async_req;
193231
err = dev->start(dev);
194232
if (err)
195-
dev->complete(dev, err);
233+
dev->complete(dev->async_req, err);
196234
}
197235

198236
static void rk_crypto_done_task_cb(unsigned long data)
199237
{
200238
struct rk_crypto_info *dev = (struct rk_crypto_info *)data;
201239

202240
if (dev->err) {
203-
dev->complete(dev, dev->err);
241+
dev->complete(dev->async_req, dev->err);
204242
return;
205243
}
206244

207245
dev->err = dev->update(dev);
208246
if (dev->err)
209-
dev->complete(dev, dev->err);
247+
dev->complete(dev->async_req, dev->err);
210248
}
211249

212250
static struct rk_crypto_tmp *rk_cipher_algs[] = {
@@ -365,6 +403,8 @@ static int rk_crypto_probe(struct platform_device *pdev)
365403
crypto_info->disable_clk = rk_crypto_disable_clk;
366404
crypto_info->load_data = rk_load_data;
367405
crypto_info->unload_data = rk_unload_data;
406+
crypto_info->enqueue = rk_crypto_enqueue;
407+
crypto_info->busy = false;
368408

369409
err = rk_crypto_register(crypto_info);
370410
if (err) {

drivers/crypto/rockchip/rk3288_crypto.h

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -192,8 +192,7 @@ struct rk_crypto_info {
192192
struct crypto_queue queue;
193193
struct tasklet_struct queue_task;
194194
struct tasklet_struct done_task;
195-
struct ablkcipher_request *ablk_req;
196-
struct ahash_request *ahash_req;
195+
struct crypto_async_request *async_req;
197196
int err;
198197
/* device lock */
199198
spinlock_t lock;
@@ -210,18 +209,20 @@ struct rk_crypto_info {
210209
size_t nents;
211210
unsigned int total;
212211
unsigned int count;
213-
u32 mode;
214212
dma_addr_t addr_in;
215213
dma_addr_t addr_out;
214+
bool busy;
216215
int (*start)(struct rk_crypto_info *dev);
217216
int (*update)(struct rk_crypto_info *dev);
218-
void (*complete)(struct rk_crypto_info *dev, int err);
217+
void (*complete)(struct crypto_async_request *base, int err);
219218
int (*enable_clk)(struct rk_crypto_info *dev);
220219
void (*disable_clk)(struct rk_crypto_info *dev);
221220
int (*load_data)(struct rk_crypto_info *dev,
222221
struct scatterlist *sg_src,
223222
struct scatterlist *sg_dst);
224223
void (*unload_data)(struct rk_crypto_info *dev);
224+
int (*enqueue)(struct rk_crypto_info *dev,
225+
struct crypto_async_request *async_req);
225226
};
226227

227228
/* the private variable of hash */
@@ -234,12 +235,14 @@ struct rk_ahash_ctx {
234235
/* the privete variable of hash for fallback */
235236
struct rk_ahash_rctx {
236237
struct ahash_request fallback_req;
238+
u32 mode;
237239
};
238240

239241
/* the private variable of cipher */
240242
struct rk_cipher_ctx {
241243
struct rk_crypto_info *dev;
242244
unsigned int keylen;
245+
u32 mode;
243246
};
244247

245248
enum alg_type {

0 commit comments

Comments
 (0)