diff options
Diffstat (limited to 'drivers/char/tpm/tpm_tis.c')
-rw-r--r-- | drivers/char/tpm/tpm_tis.c | 80 |
1 files changed, 31 insertions, 49 deletions
diff --git a/drivers/char/tpm/tpm_tis.c b/drivers/char/tpm/tpm_tis.c index ccb140d60532..36f4fec11c2a 100644 --- a/drivers/char/tpm/tpm_tis.c +++ b/drivers/char/tpm/tpm_tis.c | |||
@@ -79,9 +79,6 @@ struct priv_data { | |||
79 | bool irq_tested; | 79 | bool irq_tested; |
80 | }; | 80 | }; |
81 | 81 | ||
82 | static LIST_HEAD(tis_chips); | ||
83 | static DEFINE_MUTEX(tis_lock); | ||
84 | |||
85 | #if defined(CONFIG_PNP) && defined(CONFIG_ACPI) | 82 | #if defined(CONFIG_PNP) && defined(CONFIG_ACPI) |
86 | static int is_itpm(struct pnp_dev *dev) | 83 | static int is_itpm(struct pnp_dev *dev) |
87 | { | 84 | { |
@@ -572,6 +569,17 @@ static bool interrupts = true; | |||
572 | module_param(interrupts, bool, 0444); | 569 | module_param(interrupts, bool, 0444); |
573 | MODULE_PARM_DESC(interrupts, "Enable interrupts"); | 570 | MODULE_PARM_DESC(interrupts, "Enable interrupts"); |
574 | 571 | ||
572 | static void tpm_tis_remove(struct tpm_chip *chip) | ||
573 | { | ||
574 | iowrite32(~TPM_GLOBAL_INT_ENABLE & | ||
575 | ioread32(chip->vendor.iobase + | ||
576 | TPM_INT_ENABLE(chip->vendor. | ||
577 | locality)), | ||
578 | chip->vendor.iobase + | ||
579 | TPM_INT_ENABLE(chip->vendor.locality)); | ||
580 | release_locality(chip, chip->vendor.locality, 1); | ||
581 | } | ||
582 | |||
575 | static int tpm_tis_init(struct device *dev, resource_size_t start, | 583 | static int tpm_tis_init(struct device *dev, resource_size_t start, |
576 | resource_size_t len, unsigned int irq) | 584 | resource_size_t len, unsigned int irq) |
577 | { | 585 | { |
@@ -583,15 +591,16 @@ static int tpm_tis_init(struct device *dev, resource_size_t start, | |||
583 | priv = devm_kzalloc(dev, sizeof(struct priv_data), GFP_KERNEL); | 591 | priv = devm_kzalloc(dev, sizeof(struct priv_data), GFP_KERNEL); |
584 | if (priv == NULL) | 592 | if (priv == NULL) |
585 | return -ENOMEM; | 593 | return -ENOMEM; |
586 | if (!(chip = tpm_register_hardware(dev, &tpm_tis))) | 594 | |
587 | return -ENODEV; | 595 | chip = tpmm_chip_alloc(dev, &tpm_tis); |
596 | if (IS_ERR(chip)) | ||
597 | return PTR_ERR(chip); | ||
598 | |||
588 | chip->vendor.priv = priv; | 599 | chip->vendor.priv = priv; |
589 | 600 | ||
590 | chip->vendor.iobase = ioremap(start, len); | 601 | chip->vendor.iobase = devm_ioremap(dev, start, len); |
591 | if (!chip->vendor.iobase) { | 602 | if (!chip->vendor.iobase) |
592 | rc = -EIO; | 603 | return -EIO; |
593 | goto out_err; | ||
594 | } | ||
595 | 604 | ||
596 | /* Default timeouts */ | 605 | /* Default timeouts */ |
597 | chip->vendor.timeout_a = msecs_to_jiffies(TIS_SHORT_TIMEOUT); | 606 | chip->vendor.timeout_a = msecs_to_jiffies(TIS_SHORT_TIMEOUT); |
@@ -685,8 +694,8 @@ static int tpm_tis_init(struct device *dev, resource_size_t start, | |||
685 | for (i = irq_s; i <= irq_e && chip->vendor.irq == 0; i++) { | 694 | for (i = irq_s; i <= irq_e && chip->vendor.irq == 0; i++) { |
686 | iowrite8(i, chip->vendor.iobase + | 695 | iowrite8(i, chip->vendor.iobase + |
687 | TPM_INT_VECTOR(chip->vendor.locality)); | 696 | TPM_INT_VECTOR(chip->vendor.locality)); |
688 | if (request_irq | 697 | if (devm_request_irq |
689 | (i, tis_int_probe, IRQF_SHARED, | 698 | (dev, i, tis_int_probe, IRQF_SHARED, |
690 | chip->vendor.miscdev.name, chip) != 0) { | 699 | chip->vendor.miscdev.name, chip) != 0) { |
691 | dev_info(chip->dev, | 700 | dev_info(chip->dev, |
692 | "Unable to request irq: %d for probe\n", | 701 | "Unable to request irq: %d for probe\n", |
@@ -726,15 +735,14 @@ static int tpm_tis_init(struct device *dev, resource_size_t start, | |||
726 | iowrite32(intmask, | 735 | iowrite32(intmask, |
727 | chip->vendor.iobase + | 736 | chip->vendor.iobase + |
728 | TPM_INT_ENABLE(chip->vendor.locality)); | 737 | TPM_INT_ENABLE(chip->vendor.locality)); |
729 | free_irq(i, chip); | ||
730 | } | 738 | } |
731 | } | 739 | } |
732 | if (chip->vendor.irq) { | 740 | if (chip->vendor.irq) { |
733 | iowrite8(chip->vendor.irq, | 741 | iowrite8(chip->vendor.irq, |
734 | chip->vendor.iobase + | 742 | chip->vendor.iobase + |
735 | TPM_INT_VECTOR(chip->vendor.locality)); | 743 | TPM_INT_VECTOR(chip->vendor.locality)); |
736 | if (request_irq | 744 | if (devm_request_irq |
737 | (chip->vendor.irq, tis_int_handler, IRQF_SHARED, | 745 | (dev, chip->vendor.irq, tis_int_handler, IRQF_SHARED, |
738 | chip->vendor.miscdev.name, chip) != 0) { | 746 | chip->vendor.miscdev.name, chip) != 0) { |
739 | dev_info(chip->dev, | 747 | dev_info(chip->dev, |
740 | "Unable to request irq: %d for use\n", | 748 | "Unable to request irq: %d for use\n", |
@@ -767,17 +775,9 @@ static int tpm_tis_init(struct device *dev, resource_size_t start, | |||
767 | goto out_err; | 775 | goto out_err; |
768 | } | 776 | } |
769 | 777 | ||
770 | INIT_LIST_HEAD(&chip->vendor.list); | 778 | return tpm_chip_register(chip); |
771 | mutex_lock(&tis_lock); | ||
772 | list_add(&chip->vendor.list, &tis_chips); | ||
773 | mutex_unlock(&tis_lock); | ||
774 | |||
775 | |||
776 | return 0; | ||
777 | out_err: | 779 | out_err: |
778 | if (chip->vendor.iobase) | 780 | tpm_tis_remove(chip); |
779 | iounmap(chip->vendor.iobase); | ||
780 | tpm_remove_hardware(chip->dev); | ||
781 | return rc; | 781 | return rc; |
782 | } | 782 | } |
783 | 783 | ||
@@ -859,13 +859,10 @@ MODULE_DEVICE_TABLE(pnp, tpm_pnp_tbl); | |||
859 | static void tpm_tis_pnp_remove(struct pnp_dev *dev) | 859 | static void tpm_tis_pnp_remove(struct pnp_dev *dev) |
860 | { | 860 | { |
861 | struct tpm_chip *chip = pnp_get_drvdata(dev); | 861 | struct tpm_chip *chip = pnp_get_drvdata(dev); |
862 | 862 | tpm_chip_unregister(chip); | |
863 | tpm_dev_vendor_release(chip); | 863 | tpm_tis_remove(chip); |
864 | |||
865 | kfree(chip); | ||
866 | } | 864 | } |
867 | 865 | ||
868 | |||
869 | static struct pnp_driver tis_pnp_driver = { | 866 | static struct pnp_driver tis_pnp_driver = { |
870 | .name = "tpm_tis", | 867 | .name = "tpm_tis", |
871 | .id_table = tpm_pnp_tbl, | 868 | .id_table = tpm_pnp_tbl, |
@@ -884,7 +881,7 @@ MODULE_PARM_DESC(hid, "Set additional specific HID for this driver to probe"); | |||
884 | 881 | ||
885 | static struct platform_driver tis_drv = { | 882 | static struct platform_driver tis_drv = { |
886 | .driver = { | 883 | .driver = { |
887 | .name = "tpm_tis", | 884 | .name = "tpm_tis", |
888 | .pm = &tpm_tis_pm, | 885 | .pm = &tpm_tis_pm, |
889 | }, | 886 | }, |
890 | }; | 887 | }; |
@@ -923,31 +920,16 @@ err_dev: | |||
923 | 920 | ||
924 | static void __exit cleanup_tis(void) | 921 | static void __exit cleanup_tis(void) |
925 | { | 922 | { |
926 | struct tpm_vendor_specific *i, *j; | ||
927 | struct tpm_chip *chip; | 923 | struct tpm_chip *chip; |
928 | mutex_lock(&tis_lock); | ||
929 | list_for_each_entry_safe(i, j, &tis_chips, list) { | ||
930 | chip = to_tpm_chip(i); | ||
931 | tpm_remove_hardware(chip->dev); | ||
932 | iowrite32(~TPM_GLOBAL_INT_ENABLE & | ||
933 | ioread32(chip->vendor.iobase + | ||
934 | TPM_INT_ENABLE(chip->vendor. | ||
935 | locality)), | ||
936 | chip->vendor.iobase + | ||
937 | TPM_INT_ENABLE(chip->vendor.locality)); | ||
938 | release_locality(chip, chip->vendor.locality, 1); | ||
939 | if (chip->vendor.irq) | ||
940 | free_irq(chip->vendor.irq, chip); | ||
941 | iounmap(i->iobase); | ||
942 | list_del(&i->list); | ||
943 | } | ||
944 | mutex_unlock(&tis_lock); | ||
945 | #ifdef CONFIG_PNP | 924 | #ifdef CONFIG_PNP |
946 | if (!force) { | 925 | if (!force) { |
947 | pnp_unregister_driver(&tis_pnp_driver); | 926 | pnp_unregister_driver(&tis_pnp_driver); |
948 | return; | 927 | return; |
949 | } | 928 | } |
950 | #endif | 929 | #endif |
930 | chip = dev_get_drvdata(&pdev->dev); | ||
931 | tpm_chip_unregister(chip); | ||
932 | tpm_tis_remove(chip); | ||
951 | platform_device_unregister(pdev); | 933 | platform_device_unregister(pdev); |
952 | platform_driver_unregister(&tis_drv); | 934 | platform_driver_unregister(&tis_drv); |
953 | } | 935 | } |