Commit b5666502700855a1eb1a15482005b22478b9460e
Committed by
Kent Yoder
1 parent
61d335dd27
Exists in
smarc-l5.0.0_1.0.0-ga
and in
5 other branches
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>
Showing 2 changed files with 30 additions and 56 deletions Side-by-side Diff
drivers/char/tpm/tpm_ibmvtpm.c
... | ... | @@ -38,8 +38,6 @@ |
38 | 38 | }; |
39 | 39 | MODULE_DEVICE_TABLE(vio, tpm_ibmvtpm_device_table); |
40 | 40 | |
41 | -DECLARE_WAIT_QUEUE_HEAD(wq); | |
42 | - | |
43 | 41 | /** |
44 | 42 | * ibmvtpm_send_crq - Send a CRQ request |
45 | 43 | * @vdev: vio device struct |
... | ... | @@ -83,6 +81,7 @@ |
83 | 81 | { |
84 | 82 | struct ibmvtpm_dev *ibmvtpm; |
85 | 83 | u16 len; |
84 | + int sig; | |
86 | 85 | |
87 | 86 | ibmvtpm = (struct ibmvtpm_dev *)chip->vendor.data; |
88 | 87 | |
89 | 88 | |
90 | 89 | |
91 | 90 | |
... | ... | @@ -91,22 +90,23 @@ |
91 | 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; | |
95 | 96 | |
96 | - if (count < ibmvtpm->crq_res.len) { | |
97 | + len = ibmvtpm->res_len; | |
98 | + | |
99 | + if (count < len) { | |
97 | 100 | dev_err(ibmvtpm->dev, |
98 | 101 | "Invalid size in recv: count=%ld, crq_size=%d\n", |
99 | - count, ibmvtpm->crq_res.len); | |
102 | + count, len); | |
100 | 103 | return -EIO; |
101 | 104 | } |
102 | 105 | |
103 | 106 | spin_lock(&ibmvtpm->rtce_lock); |
104 | - memcpy((void *)buf, (void *)ibmvtpm->rtce_buf, ibmvtpm->crq_res.len); | |
105 | - memset(ibmvtpm->rtce_buf, 0, ibmvtpm->crq_res.len); | |
106 | - ibmvtpm->crq_res.valid = 0; | |
107 | - ibmvtpm->crq_res.msg = 0; | |
108 | - len = ibmvtpm->crq_res.len; | |
109 | - ibmvtpm->crq_res.len = 0; | |
107 | + memcpy((void *)buf, (void *)ibmvtpm->rtce_buf, len); | |
108 | + memset(ibmvtpm->rtce_buf, 0, len); | |
109 | + ibmvtpm->res_len = 0; | |
110 | 110 | spin_unlock(&ibmvtpm->rtce_lock); |
111 | 111 | return len; |
112 | 112 | } |
... | ... | @@ -273,7 +273,6 @@ |
273 | 273 | int rc = 0; |
274 | 274 | |
275 | 275 | free_irq(vdev->irq, ibmvtpm); |
276 | - tasklet_kill(&ibmvtpm->tasklet); | |
277 | 276 | |
278 | 277 | do { |
279 | 278 | if (rc) |
... | ... | @@ -372,7 +371,6 @@ |
372 | 371 | static int tpm_ibmvtpm_resume(struct device *dev) |
373 | 372 | { |
374 | 373 | struct ibmvtpm_dev *ibmvtpm = ibmvtpm_get_data(dev); |
375 | - unsigned long flags; | |
376 | 374 | int rc = 0; |
377 | 375 | |
378 | 376 | do { |
... | ... | @@ -387,10 +385,11 @@ |
387 | 385 | return rc; |
388 | 386 | } |
389 | 387 | |
390 | - spin_lock_irqsave(&ibmvtpm->lock, flags); | |
391 | - vio_disable_interrupts(ibmvtpm->vdev); | |
392 | - tasklet_schedule(&ibmvtpm->tasklet); | |
393 | - spin_unlock_irqrestore(&ibmvtpm->lock, flags); | |
388 | + rc = vio_enable_interrupts(ibmvtpm->vdev); | |
389 | + if (rc) { | |
390 | + dev_err(dev, "Error vio_enable_interrupts rc=%d\n", rc); | |
391 | + return rc; | |
392 | + } | |
394 | 393 | |
395 | 394 | rc = ibmvtpm_crq_send_init(ibmvtpm); |
396 | 395 | if (rc) |
... | ... | @@ -467,7 +466,7 @@ |
467 | 466 | if (crq->valid & VTPM_MSG_RES) { |
468 | 467 | if (++crq_q->index == crq_q->num_entry) |
469 | 468 | crq_q->index = 0; |
470 | - rmb(); | |
469 | + smp_rmb(); | |
471 | 470 | } else |
472 | 471 | crq = NULL; |
473 | 472 | return crq; |
... | ... | @@ -535,11 +534,9 @@ |
535 | 534 | ibmvtpm->vtpm_version = crq->data; |
536 | 535 | return; |
537 | 536 | case VTPM_TPM_COMMAND_RES: |
538 | - ibmvtpm->crq_res.valid = crq->valid; | |
539 | - ibmvtpm->crq_res.msg = crq->msg; | |
540 | - ibmvtpm->crq_res.len = crq->len; | |
541 | - ibmvtpm->crq_res.data = crq->data; | |
542 | - wake_up_interruptible(&wq); | |
537 | + /* len of the data in rtce buffer */ | |
538 | + ibmvtpm->res_len = crq->len; | |
539 | + wake_up_interruptible(&ibmvtpm->wq); | |
543 | 540 | return; |
544 | 541 | default: |
545 | 542 | return; |
546 | 543 | |
547 | 544 | |
548 | 545 | |
549 | 546 | |
... | ... | @@ -559,38 +556,19 @@ |
559 | 556 | static irqreturn_t ibmvtpm_interrupt(int irq, void *vtpm_instance) |
560 | 557 | { |
561 | 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 | 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 | 565 | while ((crq = ibmvtpm_crq_get_next(ibmvtpm)) != NULL) { |
587 | 566 | ibmvtpm_crq_process(crq, ibmvtpm); |
588 | 567 | crq->valid = 0; |
589 | - wmb(); | |
568 | + smp_wmb(); | |
590 | 569 | } |
591 | 570 | |
592 | - vio_enable_interrupts(ibmvtpm->vdev); | |
593 | - spin_unlock_irqrestore(&ibmvtpm->lock, flags); | |
571 | + return IRQ_HANDLED; | |
594 | 572 | } |
595 | 573 | |
596 | 574 | /** |
... | ... | @@ -650,9 +628,6 @@ |
650 | 628 | goto reg_crq_cleanup; |
651 | 629 | } |
652 | 630 | |
653 | - tasklet_init(&ibmvtpm->tasklet, (void *)ibmvtpm_tasklet, | |
654 | - (unsigned long)ibmvtpm); | |
655 | - | |
656 | 631 | rc = request_irq(vio_dev->irq, ibmvtpm_interrupt, 0, |
657 | 632 | tpm_ibmvtpm_driver_name, ibmvtpm); |
658 | 633 | if (rc) { |
659 | 634 | |
... | ... | @@ -666,13 +641,14 @@ |
666 | 641 | goto init_irq_cleanup; |
667 | 642 | } |
668 | 643 | |
644 | + init_waitqueue_head(&ibmvtpm->wq); | |
645 | + | |
669 | 646 | crq_q->index = 0; |
670 | 647 | |
671 | 648 | ibmvtpm->dev = dev; |
672 | 649 | ibmvtpm->vdev = vio_dev; |
673 | 650 | chip->vendor.data = (void *)ibmvtpm; |
674 | 651 | |
675 | - spin_lock_init(&ibmvtpm->lock); | |
676 | 652 | spin_lock_init(&ibmvtpm->rtce_lock); |
677 | 653 | |
678 | 654 | rc = ibmvtpm_crq_send_init(ibmvtpm); |
... | ... | @@ -689,7 +665,6 @@ |
689 | 665 | |
690 | 666 | return rc; |
691 | 667 | init_irq_cleanup: |
692 | - tasklet_kill(&ibmvtpm->tasklet); | |
693 | 668 | do { |
694 | 669 | rc1 = plpar_hcall_norets(H_FREE_CRQ, vio_dev->unit_address); |
695 | 670 | } while (rc1 == H_BUSY || H_IS_LONG_BUSY(rc1)); |
drivers/char/tpm/tpm_ibmvtpm.h
... | ... | @@ -38,13 +38,12 @@ |
38 | 38 | struct vio_dev *vdev; |
39 | 39 | struct ibmvtpm_crq_queue crq_queue; |
40 | 40 | dma_addr_t crq_dma_handle; |
41 | - spinlock_t lock; | |
42 | - struct tasklet_struct tasklet; | |
43 | 41 | u32 rtce_size; |
44 | 42 | void __iomem *rtce_buf; |
45 | 43 | dma_addr_t rtce_dma_handle; |
46 | 44 | spinlock_t rtce_lock; |
47 | - struct ibmvtpm_crq crq_res; | |
45 | + wait_queue_head_t wq; | |
46 | + u16 res_len; | |
48 | 47 | u32 vtpm_version; |
49 | 48 | }; |
50 | 49 |