diff options
author | Ashley Lai <adlai@linux.vnet.ibm.com> | 2012-09-12 13:49:50 -0400 |
---|---|---|
committer | Kent Yoder <key@linux.vnet.ibm.com> | 2012-11-01 16:23:14 -0400 |
commit | b5666502700855a1eb1a15482005b22478b9460e (patch) | |
tree | a0cefa93ace73f06a5fdf29b9b1235416c48947d /drivers/char | |
parent | 61d335dd27c67d656f114c091a46cf95cbeeb77c (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.c | 81 | ||||
-rw-r--r-- | drivers/char/tpm/tpm_ibmvtpm.h | 5 |
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 | }; |
39 | MODULE_DEVICE_TABLE(vio, tpm_ibmvtpm_device_table); | 39 | MODULE_DEVICE_TABLE(vio, tpm_ibmvtpm_device_table); |
40 | 40 | ||
41 | DECLARE_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) | |||
372 | static int tpm_ibmvtpm_resume(struct device *dev) | 371 | static 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, | |||
559 | static irqreturn_t ibmvtpm_interrupt(int irq, void *vtpm_instance) | 556 | static 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 | **/ | ||
579 | static 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; |
691 | init_irq_cleanup: | 667 | init_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 | ||