diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/crypto/omap-sham.c | 40 |
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[] = { | |||
1033 | static void omap_sham_done_task(unsigned long data) | 1036 | static 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)) { | 1068 | finish: |
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 | ||
1061 | static irqreturn_t omap_sham_irq(int irq, void *dev_id) | 1074 | static 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 | ||