aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/crypto/omap-sham.c40
1 files changed, 27 insertions, 13 deletions
diff --git a/drivers/crypto/omap-sham.c b/drivers/crypto/omap-sham.c
index 24de4ace9783..a8de7b890d45 100644
--- a/drivers/crypto/omap-sham.c
+++ b/drivers/crypto/omap-sham.c
@@ -79,6 +79,7 @@
79#define FLAGS_OUTPUT_READY 3 79#define FLAGS_OUTPUT_READY 3
80#define FLAGS_INIT 4 80#define FLAGS_INIT 4
81#define FLAGS_CPU 5 81#define FLAGS_CPU 5
82#define FLAGS_DMA_READY 6
82/* context flags */ 83/* context flags */
83#define FLAGS_FINUP 16 84#define FLAGS_FINUP 16
84#define FLAGS_SG 17 85#define FLAGS_SG 17
@@ -304,6 +305,8 @@ static int omap_sham_xmit_cpu(struct omap_sham_dev *dd, const u8 *buf,
304 if (final) 305 if (final)
305 set_bit(FLAGS_FINAL, &dd->flags); /* catch last interrupt */ 306 set_bit(FLAGS_FINAL, &dd->flags); /* catch last interrupt */
306 307
308 set_bit(FLAGS_CPU, &dd->flags);
309
307 len32 = DIV_ROUND_UP(length, sizeof(u32)); 310 len32 = DIV_ROUND_UP(length, sizeof(u32));
308 311
309 for (count = 0; count < len32; count++) 312 for (count = 0; count < len32; count++)
@@ -1033,29 +1036,39 @@ static struct ahash_alg algs[] = {
1033static void omap_sham_done_task(unsigned long data) 1036static void omap_sham_done_task(unsigned long data)
1034{ 1037{
1035 struct omap_sham_dev *dd = (struct omap_sham_dev *)data; 1038 struct omap_sham_dev *dd = (struct omap_sham_dev *)data;
1036 int ready = 0, err = 0; 1039 int err = 0;
1037 1040
1038 if (!test_bit(FLAGS_BUSY, &dd->flags)) { 1041 if (!test_bit(FLAGS_BUSY, &dd->flags)) {
1039 omap_sham_handle_queue(dd, NULL); 1042 omap_sham_handle_queue(dd, NULL);
1040 return; 1043 return;
1041 } 1044 }
1042 1045
1043 if (test_and_clear_bit(FLAGS_OUTPUT_READY, &dd->flags)) 1046 if (test_bit(FLAGS_CPU, &dd->flags)) {
1044 ready = 1; 1047 if (test_and_clear_bit(FLAGS_OUTPUT_READY, &dd->flags))
1045 1048 goto finish;
1046 if (test_and_clear_bit(FLAGS_DMA_ACTIVE, &dd->flags)) { 1049 } else if (test_bit(FLAGS_DMA_READY, &dd->flags)) {
1047 omap_sham_update_dma_stop(dd); 1050 if (test_and_clear_bit(FLAGS_DMA_ACTIVE, &dd->flags)) {
1048 if (!dd->err) 1051 omap_sham_update_dma_stop(dd);
1052 if (dd->err) {
1053 err = dd->err;
1054 goto finish;
1055 }
1056 }
1057 if (test_and_clear_bit(FLAGS_OUTPUT_READY, &dd->flags)) {
1058 /* hash or semi-hash ready */
1059 clear_bit(FLAGS_DMA_READY, &dd->flags);
1049 err = omap_sham_update_dma_start(dd); 1060 err = omap_sham_update_dma_start(dd);
1061 if (err != -EINPROGRESS)
1062 goto finish;
1063 }
1050 } 1064 }
1051 1065
1052 err = dd->err ? : err; 1066 return;
1053 1067
1054 if (err != -EINPROGRESS && (ready || err)) { 1068finish:
1055 dev_dbg(dd->dev, "update done: err: %d\n", err); 1069 dev_dbg(dd->dev, "update done: err: %d\n", err);
1056 /* finish curent request */ 1070 /* finish curent request */
1057 omap_sham_finish_req(dd->req, err); 1071 omap_sham_finish_req(dd->req, err);
1058 }
1059} 1072}
1060 1073
1061static irqreturn_t omap_sham_irq(int irq, void *dev_id) 1074static irqreturn_t omap_sham_irq(int irq, void *dev_id)
@@ -1087,6 +1100,7 @@ static void omap_sham_dma_callback(int lch, u16 ch_status, void *data)
1087 clear_bit(FLAGS_INIT, &dd->flags);/* request to re-initialize */ 1100 clear_bit(FLAGS_INIT, &dd->flags);/* request to re-initialize */
1088 } 1101 }
1089 1102
1103 set_bit(FLAGS_DMA_READY, &dd->flags);
1090 tasklet_schedule(&dd->done_task); 1104 tasklet_schedule(&dd->done_task);
1091} 1105}
1092 1106