aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/crypto/ccp
diff options
context:
space:
mode:
authorTom Lendacky <thomas.lendacky@amd.com>2014-01-24 17:18:14 -0500
committerHerbert Xu <herbert@gondor.apana.org.au>2014-02-08 20:59:24 -0500
commit530abd89387b5213000b214be64fadd8ab3176a7 (patch)
tree4ae9837b683f5ebd150f281dd574e44c912baf44 /drivers/crypto/ccp
parentbc3854476f36d816d52cd8d41d1ecab2f8b6cdcf (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.c21
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");
30MODULE_VERSION("1.0.0"); 30MODULE_VERSION("1.0.0");
31MODULE_DESCRIPTION("AMD Cryptographic Coprocessor driver"); 31MODULE_DESCRIPTION("AMD Cryptographic Coprocessor driver");
32 32
33struct ccp_tasklet_data {
34 struct completion completion;
35 struct ccp_cmd *cmd;
36};
37
33 38
34static struct ccp_device *ccp_dev; 39static struct ccp_device *ccp_dev;
35static inline struct ccp_device *ccp_get_device(void) 40static 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
195static void ccp_do_cmd_complete(struct work_struct *work) 200static 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
202static int ccp_cmd_queue_thread(void *data) 209static 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);