aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char
diff options
context:
space:
mode:
authorAshley Lai <adlai@linux.vnet.ibm.com>2012-09-12 13:49:50 -0400
committerKent Yoder <key@linux.vnet.ibm.com>2012-11-01 16:23:14 -0400
commitb5666502700855a1eb1a15482005b22478b9460e (patch)
treea0cefa93ace73f06a5fdf29b9b1235416c48947d /drivers/char
parent61d335dd27c67d656f114c091a46cf95cbeeb77c (diff)
drivers/char/tpm: remove tasklet and cleanup
This patch removed the tasklet and moved the wait queue into the private structure. It also cleaned up the response CRQ path. Signed-off-by: Ashley Lai <adlai@us.ibm.com> Signed-off-by: Kent Yoder <key@linux.vnet.ibm.com>
Diffstat (limited to 'drivers/char')
-rw-r--r--drivers/char/tpm/tpm_ibmvtpm.c81
-rw-r--r--drivers/char/tpm/tpm_ibmvtpm.h5
2 files changed, 30 insertions, 56 deletions
diff --git a/drivers/char/tpm/tpm_ibmvtpm.c b/drivers/char/tpm/tpm_ibmvtpm.c
index efc4ab36a9d6..88a95ea2ba03 100644
--- a/drivers/char/tpm/tpm_ibmvtpm.c
+++ b/drivers/char/tpm/tpm_ibmvtpm.c
@@ -38,8 +38,6 @@ static struct vio_device_id tpm_ibmvtpm_device_table[] __devinitdata = {
38}; 38};
39MODULE_DEVICE_TABLE(vio, tpm_ibmvtpm_device_table); 39MODULE_DEVICE_TABLE(vio, tpm_ibmvtpm_device_table);
40 40
41DECLARE_WAIT_QUEUE_HEAD(wq);
42
43/** 41/**
44 * ibmvtpm_send_crq - Send a CRQ request 42 * ibmvtpm_send_crq - Send a CRQ request
45 * @vdev: vio device struct 43 * @vdev: vio device struct
@@ -83,6 +81,7 @@ static int tpm_ibmvtpm_recv(struct tpm_chip *chip, u8 *buf, size_t count)
83{ 81{
84 struct ibmvtpm_dev *ibmvtpm; 82 struct ibmvtpm_dev *ibmvtpm;
85 u16 len; 83 u16 len;
84 int sig;
86 85
87 ibmvtpm = (struct ibmvtpm_dev *)chip->vendor.data; 86 ibmvtpm = (struct ibmvtpm_dev *)chip->vendor.data;
88 87
@@ -91,22 +90,23 @@ static int tpm_ibmvtpm_recv(struct tpm_chip *chip, u8 *buf, size_t count)
91 return 0; 90 return 0;
92 } 91 }
93 92
94 wait_event_interruptible(wq, ibmvtpm->crq_res.len != 0); 93 sig = wait_event_interruptible(ibmvtpm->wq, ibmvtpm->res_len != 0);
94 if (sig)
95 return -EINTR;
96
97 len = ibmvtpm->res_len;
95 98
96 if (count < ibmvtpm->crq_res.len) { 99 if (count < len) {
97 dev_err(ibmvtpm->dev, 100 dev_err(ibmvtpm->dev,
98 "Invalid size in recv: count=%ld, crq_size=%d\n", 101 "Invalid size in recv: count=%ld, crq_size=%d\n",
99 count, ibmvtpm->crq_res.len); 102 count, len);
100 return -EIO; 103 return -EIO;
101 } 104 }
102 105
103 spin_lock(&ibmvtpm->rtce_lock); 106 spin_lock(&ibmvtpm->rtce_lock);
104 memcpy((void *)buf, (void *)ibmvtpm->rtce_buf, ibmvtpm->crq_res.len); 107 memcpy((void *)buf, (void *)ibmvtpm->rtce_buf, len);
105 memset(ibmvtpm->rtce_buf, 0, ibmvtpm->crq_res.len); 108 memset(ibmvtpm->rtce_buf, 0, len);
106 ibmvtpm->crq_res.valid = 0; 109 ibmvtpm->res_len = 0;
107 ibmvtpm->crq_res.msg = 0;
108 len = ibmvtpm->crq_res.len;
109 ibmvtpm->crq_res.len = 0;
110 spin_unlock(&ibmvtpm->rtce_lock); 110 spin_unlock(&ibmvtpm->rtce_lock);
111 return len; 111 return len;
112} 112}
@@ -273,7 +273,6 @@ static int __devexit tpm_ibmvtpm_remove(struct vio_dev *vdev)
273 int rc = 0; 273 int rc = 0;
274 274
275 free_irq(vdev->irq, ibmvtpm); 275 free_irq(vdev->irq, ibmvtpm);
276 tasklet_kill(&ibmvtpm->tasklet);
277 276
278 do { 277 do {
279 if (rc) 278 if (rc)
@@ -372,7 +371,6 @@ static int ibmvtpm_reset_crq(struct ibmvtpm_dev *ibmvtpm)
372static int tpm_ibmvtpm_resume(struct device *dev) 371static int tpm_ibmvtpm_resume(struct device *dev)
373{ 372{
374 struct ibmvtpm_dev *ibmvtpm = ibmvtpm_get_data(dev); 373 struct ibmvtpm_dev *ibmvtpm = ibmvtpm_get_data(dev);
375 unsigned long flags;
376 int rc = 0; 374 int rc = 0;
377 375
378 do { 376 do {
@@ -387,10 +385,11 @@ static int tpm_ibmvtpm_resume(struct device *dev)
387 return rc; 385 return rc;
388 } 386 }
389 387
390 spin_lock_irqsave(&ibmvtpm->lock, flags); 388 rc = vio_enable_interrupts(ibmvtpm->vdev);
391 vio_disable_interrupts(ibmvtpm->vdev); 389 if (rc) {
392 tasklet_schedule(&ibmvtpm->tasklet); 390 dev_err(dev, "Error vio_enable_interrupts rc=%d\n", rc);
393 spin_unlock_irqrestore(&ibmvtpm->lock, flags); 391 return rc;
392 }
394 393
395 rc = ibmvtpm_crq_send_init(ibmvtpm); 394 rc = ibmvtpm_crq_send_init(ibmvtpm);
396 if (rc) 395 if (rc)
@@ -467,7 +466,7 @@ static struct ibmvtpm_crq *ibmvtpm_crq_get_next(struct ibmvtpm_dev *ibmvtpm)
467 if (crq->valid & VTPM_MSG_RES) { 466 if (crq->valid & VTPM_MSG_RES) {
468 if (++crq_q->index == crq_q->num_entry) 467 if (++crq_q->index == crq_q->num_entry)
469 crq_q->index = 0; 468 crq_q->index = 0;
470 rmb(); 469 smp_rmb();
471 } else 470 } else
472 crq = NULL; 471 crq = NULL;
473 return crq; 472 return crq;
@@ -535,11 +534,9 @@ static void ibmvtpm_crq_process(struct ibmvtpm_crq *crq,
535 ibmvtpm->vtpm_version = crq->data; 534 ibmvtpm->vtpm_version = crq->data;
536 return; 535 return;
537 case VTPM_TPM_COMMAND_RES: 536 case VTPM_TPM_COMMAND_RES:
538 ibmvtpm->crq_res.valid = crq->valid; 537 /* len of the data in rtce buffer */
539 ibmvtpm->crq_res.msg = crq->msg; 538 ibmvtpm->res_len = crq->len;
540 ibmvtpm->crq_res.len = crq->len; 539 wake_up_interruptible(&ibmvtpm->wq);
541 ibmvtpm->crq_res.data = crq->data;
542 wake_up_interruptible(&wq);
543 return; 540 return;
544 default: 541 default:
545 return; 542 return;
@@ -559,38 +556,19 @@ static void ibmvtpm_crq_process(struct ibmvtpm_crq *crq,
559static irqreturn_t ibmvtpm_interrupt(int irq, void *vtpm_instance) 556static irqreturn_t ibmvtpm_interrupt(int irq, void *vtpm_instance)
560{ 557{
561 struct ibmvtpm_dev *ibmvtpm = (struct ibmvtpm_dev *) vtpm_instance; 558 struct ibmvtpm_dev *ibmvtpm = (struct ibmvtpm_dev *) vtpm_instance;
562 unsigned long flags;
563
564 spin_lock_irqsave(&ibmvtpm->lock, flags);
565 vio_disable_interrupts(ibmvtpm->vdev);
566 tasklet_schedule(&ibmvtpm->tasklet);
567 spin_unlock_irqrestore(&ibmvtpm->lock, flags);
568
569 return IRQ_HANDLED;
570}
571
572/**
573 * ibmvtpm_tasklet - Interrupt handler tasklet
574 * @data: ibm vtpm device struct
575 *
576 * Returns:
577 * Nothing
578 **/
579static void ibmvtpm_tasklet(void *data)
580{
581 struct ibmvtpm_dev *ibmvtpm = data;
582 struct ibmvtpm_crq *crq; 559 struct ibmvtpm_crq *crq;
583 unsigned long flags;
584 560
585 spin_lock_irqsave(&ibmvtpm->lock, flags); 561 /* while loop is needed for initial setup (get version and
562 * get rtce_size). There should be only one tpm request at any
563 * given time.
564 */
586 while ((crq = ibmvtpm_crq_get_next(ibmvtpm)) != NULL) { 565 while ((crq = ibmvtpm_crq_get_next(ibmvtpm)) != NULL) {
587 ibmvtpm_crq_process(crq, ibmvtpm); 566 ibmvtpm_crq_process(crq, ibmvtpm);
588 crq->valid = 0; 567 crq->valid = 0;
589 wmb(); 568 smp_wmb();
590 } 569 }
591 570
592 vio_enable_interrupts(ibmvtpm->vdev); 571 return IRQ_HANDLED;
593 spin_unlock_irqrestore(&ibmvtpm->lock, flags);
594} 572}
595 573
596/** 574/**
@@ -650,9 +628,6 @@ static int __devinit tpm_ibmvtpm_probe(struct vio_dev *vio_dev,
650 goto reg_crq_cleanup; 628 goto reg_crq_cleanup;
651 } 629 }
652 630
653 tasklet_init(&ibmvtpm->tasklet, (void *)ibmvtpm_tasklet,
654 (unsigned long)ibmvtpm);
655
656 rc = request_irq(vio_dev->irq, ibmvtpm_interrupt, 0, 631 rc = request_irq(vio_dev->irq, ibmvtpm_interrupt, 0,
657 tpm_ibmvtpm_driver_name, ibmvtpm); 632 tpm_ibmvtpm_driver_name, ibmvtpm);
658 if (rc) { 633 if (rc) {
@@ -666,13 +641,14 @@ static int __devinit tpm_ibmvtpm_probe(struct vio_dev *vio_dev,
666 goto init_irq_cleanup; 641 goto init_irq_cleanup;
667 } 642 }
668 643
644 init_waitqueue_head(&ibmvtpm->wq);
645
669 crq_q->index = 0; 646 crq_q->index = 0;
670 647
671 ibmvtpm->dev = dev; 648 ibmvtpm->dev = dev;
672 ibmvtpm->vdev = vio_dev; 649 ibmvtpm->vdev = vio_dev;
673 chip->vendor.data = (void *)ibmvtpm; 650 chip->vendor.data = (void *)ibmvtpm;
674 651
675 spin_lock_init(&ibmvtpm->lock);
676 spin_lock_init(&ibmvtpm->rtce_lock); 652 spin_lock_init(&ibmvtpm->rtce_lock);
677 653
678 rc = ibmvtpm_crq_send_init(ibmvtpm); 654 rc = ibmvtpm_crq_send_init(ibmvtpm);
@@ -689,7 +665,6 @@ static int __devinit tpm_ibmvtpm_probe(struct vio_dev *vio_dev,
689 665
690 return rc; 666 return rc;
691init_irq_cleanup: 667init_irq_cleanup:
692 tasklet_kill(&ibmvtpm->tasklet);
693 do { 668 do {
694 rc1 = plpar_hcall_norets(H_FREE_CRQ, vio_dev->unit_address); 669 rc1 = plpar_hcall_norets(H_FREE_CRQ, vio_dev->unit_address);
695 } while (rc1 == H_BUSY || H_IS_LONG_BUSY(rc1)); 670 } while (rc1 == H_BUSY || H_IS_LONG_BUSY(rc1));
diff --git a/drivers/char/tpm/tpm_ibmvtpm.h b/drivers/char/tpm/tpm_ibmvtpm.h
index 4296eb4b4d82..bd82a791f995 100644
--- a/drivers/char/tpm/tpm_ibmvtpm.h
+++ b/drivers/char/tpm/tpm_ibmvtpm.h
@@ -38,13 +38,12 @@ struct ibmvtpm_dev {
38 struct vio_dev *vdev; 38 struct vio_dev *vdev;
39 struct ibmvtpm_crq_queue crq_queue; 39 struct ibmvtpm_crq_queue crq_queue;
40 dma_addr_t crq_dma_handle; 40 dma_addr_t crq_dma_handle;
41 spinlock_t lock;
42 struct tasklet_struct tasklet;
43 u32 rtce_size; 41 u32 rtce_size;
44 void __iomem *rtce_buf; 42 void __iomem *rtce_buf;
45 dma_addr_t rtce_dma_handle; 43 dma_addr_t rtce_dma_handle;
46 spinlock_t rtce_lock; 44 spinlock_t rtce_lock;
47 struct ibmvtpm_crq crq_res; 45 wait_queue_head_t wq;
46 u16 res_len;
48 u32 vtpm_version; 47 u32 vtpm_version;
49}; 48};
50 49