aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/crypto/mv_cesa.c41
1 files changed, 31 insertions, 10 deletions
diff --git a/drivers/crypto/mv_cesa.c b/drivers/crypto/mv_cesa.c
index 1cc6b3f3e262..b0b2f02518f8 100644
--- a/drivers/crypto/mv_cesa.c
+++ b/drivers/crypto/mv_cesa.c
@@ -24,6 +24,7 @@
24 24
25#define MV_CESA "MV-CESA:" 25#define MV_CESA "MV-CESA:"
26#define MAX_HW_HASH_SIZE 0xFFFF 26#define MAX_HW_HASH_SIZE 0xFFFF
27#define MV_CESA_EXPIRE 500 /* msec */
27 28
28/* 29/*
29 * STM: 30 * STM:
@@ -87,6 +88,7 @@ struct crypto_priv {
87 spinlock_t lock; 88 spinlock_t lock;
88 struct crypto_queue queue; 89 struct crypto_queue queue;
89 enum engine_status eng_st; 90 enum engine_status eng_st;
91 struct timer_list completion_timer;
90 struct crypto_async_request *cur_req; 92 struct crypto_async_request *cur_req;
91 struct req_progress p; 93 struct req_progress p;
92 int max_req_size; 94 int max_req_size;
@@ -138,6 +140,29 @@ struct mv_req_hash_ctx {
138 int count_add; 140 int count_add;
139}; 141};
140 142
143static void mv_completion_timer_callback(unsigned long unused)
144{
145 int active = readl(cpg->reg + SEC_ACCEL_CMD) & SEC_CMD_EN_SEC_ACCL0;
146
147 printk(KERN_ERR MV_CESA
148 "completion timer expired (CESA %sactive), cleaning up.\n",
149 active ? "" : "in");
150
151 del_timer(&cpg->completion_timer);
152 writel(SEC_CMD_DISABLE_SEC, cpg->reg + SEC_ACCEL_CMD);
153 while(readl(cpg->reg + SEC_ACCEL_CMD) & SEC_CMD_DISABLE_SEC)
154 printk(KERN_INFO MV_CESA "%s: waiting for engine finishing\n", __func__);
155 cpg->eng_st = ENGINE_W_DEQUEUE;
156 wake_up_process(cpg->queue_th);
157}
158
159static void mv_setup_timer(void)
160{
161 setup_timer(&cpg->completion_timer, &mv_completion_timer_callback, 0);
162 mod_timer(&cpg->completion_timer,
163 jiffies + msecs_to_jiffies(MV_CESA_EXPIRE));
164}
165
141static void compute_aes_dec_key(struct mv_ctx *ctx) 166static void compute_aes_dec_key(struct mv_ctx *ctx)
142{ 167{
143 struct crypto_aes_ctx gen_aes_key; 168 struct crypto_aes_ctx gen_aes_key;
@@ -273,12 +298,8 @@ static void mv_process_current_q(int first_block)
273 sizeof(struct sec_accel_config)); 298 sizeof(struct sec_accel_config));
274 299
275 /* GO */ 300 /* GO */
301 mv_setup_timer();
276 writel(SEC_CMD_EN_SEC_ACCL0, cpg->reg + SEC_ACCEL_CMD); 302 writel(SEC_CMD_EN_SEC_ACCL0, cpg->reg + SEC_ACCEL_CMD);
277
278 /*
279 * XXX: add timer if the interrupt does not occur for some mystery
280 * reason
281 */
282} 303}
283 304
284static void mv_crypto_algo_completion(void) 305static void mv_crypto_algo_completion(void)
@@ -357,12 +378,8 @@ static void mv_process_hash_current(int first_block)
357 memcpy(cpg->sram + SRAM_CONFIG, &op, sizeof(struct sec_accel_config)); 378 memcpy(cpg->sram + SRAM_CONFIG, &op, sizeof(struct sec_accel_config));
358 379
359 /* GO */ 380 /* GO */
381 mv_setup_timer();
360 writel(SEC_CMD_EN_SEC_ACCL0, cpg->reg + SEC_ACCEL_CMD); 382 writel(SEC_CMD_EN_SEC_ACCL0, cpg->reg + SEC_ACCEL_CMD);
361
362 /*
363 * XXX: add timer if the interrupt does not occur for some mystery
364 * reason
365 */
366} 383}
367 384
368static inline int mv_hash_import_sha1_ctx(const struct mv_req_hash_ctx *ctx, 385static inline int mv_hash_import_sha1_ctx(const struct mv_req_hash_ctx *ctx,
@@ -888,6 +905,10 @@ irqreturn_t crypto_int(int irq, void *priv)
888 if (!(val & SEC_INT_ACCEL0_DONE)) 905 if (!(val & SEC_INT_ACCEL0_DONE))
889 return IRQ_NONE; 906 return IRQ_NONE;
890 907
908 if (!del_timer(&cpg->completion_timer)) {
909 printk(KERN_WARNING MV_CESA
910 "got an interrupt but no pending timer?\n");
911 }
891 val &= ~SEC_INT_ACCEL0_DONE; 912 val &= ~SEC_INT_ACCEL0_DONE;
892 writel(val, cpg->reg + FPGA_INT_STATUS); 913 writel(val, cpg->reg + FPGA_INT_STATUS);
893 writel(val, cpg->reg + SEC_ACCEL_INT_STATUS); 914 writel(val, cpg->reg + SEC_ACCEL_INT_STATUS);