diff options
-rw-r--r-- | drivers/crypto/mv_cesa.c | 41 |
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 | ||
143 | static 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 | |||
159 | static 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 | |||
141 | static void compute_aes_dec_key(struct mv_ctx *ctx) | 166 | static 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 | ||
284 | static void mv_crypto_algo_completion(void) | 305 | static 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 | ||
368 | static inline int mv_hash_import_sha1_ctx(const struct mv_req_hash_ctx *ctx, | 385 | static 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); |