diff options
author | Tom Lendacky <thomas.lendacky@amd.com> | 2014-01-24 17:18:14 -0500 |
---|---|---|
committer | Herbert Xu <herbert@gondor.apana.org.au> | 2014-02-08 20:59:24 -0500 |
commit | 530abd89387b5213000b214be64fadd8ab3176a7 (patch) | |
tree | 4ae9837b683f5ebd150f281dd574e44c912baf44 /drivers/crypto/ccp | |
parent | bc3854476f36d816d52cd8d41d1ecab2f8b6cdcf (diff) |
crypto: ccp - Perform completion callbacks using a tasklet
Change from scheduling work to scheduling a tasklet to perform
the callback operations.
Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Diffstat (limited to 'drivers/crypto/ccp')
-rw-r--r-- | drivers/crypto/ccp/ccp-dev.c | 21 |
1 files changed, 17 insertions, 4 deletions
diff --git a/drivers/crypto/ccp/ccp-dev.c b/drivers/crypto/ccp/ccp-dev.c index c3bc21264600..2c7816149b01 100644 --- a/drivers/crypto/ccp/ccp-dev.c +++ b/drivers/crypto/ccp/ccp-dev.c | |||
@@ -30,6 +30,11 @@ MODULE_LICENSE("GPL"); | |||
30 | MODULE_VERSION("1.0.0"); | 30 | MODULE_VERSION("1.0.0"); |
31 | MODULE_DESCRIPTION("AMD Cryptographic Coprocessor driver"); | 31 | MODULE_DESCRIPTION("AMD Cryptographic Coprocessor driver"); |
32 | 32 | ||
33 | struct ccp_tasklet_data { | ||
34 | struct completion completion; | ||
35 | struct ccp_cmd *cmd; | ||
36 | }; | ||
37 | |||
33 | 38 | ||
34 | static struct ccp_device *ccp_dev; | 39 | static struct ccp_device *ccp_dev; |
35 | static inline struct ccp_device *ccp_get_device(void) | 40 | static inline struct ccp_device *ccp_get_device(void) |
@@ -192,17 +197,23 @@ static struct ccp_cmd *ccp_dequeue_cmd(struct ccp_cmd_queue *cmd_q) | |||
192 | return cmd; | 197 | return cmd; |
193 | } | 198 | } |
194 | 199 | ||
195 | static void ccp_do_cmd_complete(struct work_struct *work) | 200 | static void ccp_do_cmd_complete(unsigned long data) |
196 | { | 201 | { |
197 | struct ccp_cmd *cmd = container_of(work, struct ccp_cmd, work); | 202 | struct ccp_tasklet_data *tdata = (struct ccp_tasklet_data *)data; |
203 | struct ccp_cmd *cmd = tdata->cmd; | ||
198 | 204 | ||
199 | cmd->callback(cmd->data, cmd->ret); | 205 | cmd->callback(cmd->data, cmd->ret); |
206 | complete(&tdata->completion); | ||
200 | } | 207 | } |
201 | 208 | ||
202 | static int ccp_cmd_queue_thread(void *data) | 209 | static int ccp_cmd_queue_thread(void *data) |
203 | { | 210 | { |
204 | struct ccp_cmd_queue *cmd_q = (struct ccp_cmd_queue *)data; | 211 | struct ccp_cmd_queue *cmd_q = (struct ccp_cmd_queue *)data; |
205 | struct ccp_cmd *cmd; | 212 | struct ccp_cmd *cmd; |
213 | struct ccp_tasklet_data tdata; | ||
214 | struct tasklet_struct tasklet; | ||
215 | |||
216 | tasklet_init(&tasklet, ccp_do_cmd_complete, (unsigned long)&tdata); | ||
206 | 217 | ||
207 | set_current_state(TASK_INTERRUPTIBLE); | 218 | set_current_state(TASK_INTERRUPTIBLE); |
208 | while (!kthread_should_stop()) { | 219 | while (!kthread_should_stop()) { |
@@ -220,8 +231,10 @@ static int ccp_cmd_queue_thread(void *data) | |||
220 | cmd->ret = ccp_run_cmd(cmd_q, cmd); | 231 | cmd->ret = ccp_run_cmd(cmd_q, cmd); |
221 | 232 | ||
222 | /* Schedule the completion callback */ | 233 | /* Schedule the completion callback */ |
223 | INIT_WORK(&cmd->work, ccp_do_cmd_complete); | 234 | tdata.cmd = cmd; |
224 | schedule_work(&cmd->work); | 235 | init_completion(&tdata.completion); |
236 | tasklet_schedule(&tasklet); | ||
237 | wait_for_completion(&tdata.completion); | ||
225 | } | 238 | } |
226 | 239 | ||
227 | __set_current_state(TASK_RUNNING); | 240 | __set_current_state(TASK_RUNNING); |