Skip to content

Commit 0019482

Browse files
jgunthorpeJarkko Sakkinen
authored andcommitted
tpm_tis: Clean up the force=1 module parameter
The TPM core has long assumed that every device has a driver attached, however the force path was attaching the TPM core outside of a driver context. This isn't generally reliable as the user could detatch the driver using sysfs or something, but commit b8b2c7d ("base/platform: assert that dev_pm_domain callbacks are called unconditionally") forced the issue by leaving the driver pointer NULL if there is no probe. Rework the TPM setup to create a platform device with resources and then allow the driver core to naturally bind and probe it through the normal mechanisms. All this structure is needed anyhow to enable TPM for OF environments. Finally, since the entire flow is changing convert the init/exit to use the modern ifdef-less coding style when possible Reported-by: "Wilck, Martin" <martin.wilck@ts.fujitsu.com> Signed-off-by: Jason Gunthorpe <jgunthorpe@obsidianresearch.com> Tested-by: Wilck, Martin <martin.wilck@ts.fujitsu.com> Tested-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com> Reviewed-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com> Acked-by: Peter Huewe <peterhuewe@gmx.de>
1 parent 51dd43d commit 0019482

File tree

1 file changed

+104
-65
lines changed

1 file changed

+104
-65
lines changed

drivers/char/tpm/tpm_tis.c

Lines changed: 104 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,6 @@ enum tis_int_flags {
5959
};
6060

6161
enum tis_defaults {
62-
TIS_MEM_BASE = 0xFED40000,
6362
TIS_MEM_LEN = 0x5000,
6463
TIS_SHORT_TIMEOUT = 750, /* ms */
6564
TIS_LONG_TIMEOUT = 2000, /* 2 sec */
@@ -74,15 +73,6 @@ struct tpm_info {
7473
int irq;
7574
};
7675

77-
static struct tpm_info tis_default_info = {
78-
.res = {
79-
.start = TIS_MEM_BASE,
80-
.end = TIS_MEM_BASE + TIS_MEM_LEN - 1,
81-
.flags = IORESOURCE_MEM,
82-
},
83-
.irq = 0,
84-
};
85-
8676
/* Some timeout values are needed before it is known whether the chip is
8777
* TPM 1.0 or TPM 2.0.
8878
*/
@@ -824,7 +814,6 @@ static int tpm_tis_init(struct device *dev, struct tpm_info *tpm_info,
824814
return rc;
825815
}
826816

827-
#ifdef CONFIG_PM_SLEEP
828817
static void tpm_tis_reenable_interrupts(struct tpm_chip *chip)
829818
{
830819
u32 intmask;
@@ -866,11 +855,9 @@ static int tpm_tis_resume(struct device *dev)
866855

867856
return 0;
868857
}
869-
#endif
870858

871859
static SIMPLE_DEV_PM_OPS(tpm_tis_pm, tpm_pm_suspend, tpm_tis_resume);
872860

873-
#ifdef CONFIG_PNP
874861
static int tpm_tis_pnp_init(struct pnp_dev *pnp_dev,
875862
const struct pnp_device_id *pnp_id)
876863
{
@@ -888,14 +875,12 @@ static int tpm_tis_pnp_init(struct pnp_dev *pnp_dev,
888875
else
889876
tpm_info.irq = -1;
890877

891-
#ifdef CONFIG_ACPI
892878
if (pnp_acpi_device(pnp_dev)) {
893879
if (is_itpm(pnp_acpi_device(pnp_dev)))
894880
itpm = true;
895881

896-
acpi_dev_handle = pnp_acpi_device(pnp_dev)->handle;
882+
acpi_dev_handle = ACPI_HANDLE(&pnp_dev->dev);
897883
}
898-
#endif
899884

900885
return tpm_tis_init(&pnp_dev->dev, &tpm_info, acpi_dev_handle);
901886
}
@@ -936,7 +921,6 @@ static struct pnp_driver tis_pnp_driver = {
936921
module_param_string(hid, tpm_pnp_tbl[TIS_HID_USR_IDX].id,
937922
sizeof(tpm_pnp_tbl[TIS_HID_USR_IDX].id), 0444);
938923
MODULE_PARM_DESC(hid, "Set additional specific HID for this driver to probe");
939-
#endif
940924

941925
#ifdef CONFIG_ACPI
942926
static int tpm_check_resource(struct acpi_resource *ares, void *data)
@@ -1023,80 +1007,135 @@ static struct acpi_driver tis_acpi_driver = {
10231007
};
10241008
#endif
10251009

1010+
static struct platform_device *force_pdev;
1011+
1012+
static int tpm_tis_plat_probe(struct platform_device *pdev)
1013+
{
1014+
struct tpm_info tpm_info = {};
1015+
struct resource *res;
1016+
1017+
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1018+
if (res == NULL) {
1019+
dev_err(&pdev->dev, "no memory resource defined\n");
1020+
return -ENODEV;
1021+
}
1022+
tpm_info.res = *res;
1023+
1024+
res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
1025+
if (res) {
1026+
tpm_info.irq = res->start;
1027+
} else {
1028+
if (pdev == force_pdev)
1029+
tpm_info.irq = -1;
1030+
else
1031+
/* When forcing auto probe the IRQ */
1032+
tpm_info.irq = 0;
1033+
}
1034+
1035+
return tpm_tis_init(&pdev->dev, &tpm_info, NULL);
1036+
}
1037+
1038+
static int tpm_tis_plat_remove(struct platform_device *pdev)
1039+
{
1040+
struct tpm_chip *chip = dev_get_drvdata(&pdev->dev);
1041+
1042+
tpm_chip_unregister(chip);
1043+
tpm_tis_remove(chip);
1044+
1045+
return 0;
1046+
}
1047+
10261048
static struct platform_driver tis_drv = {
1049+
.probe = tpm_tis_plat_probe,
1050+
.remove = tpm_tis_plat_remove,
10271051
.driver = {
10281052
.name = "tpm_tis",
10291053
.pm = &tpm_tis_pm,
10301054
},
10311055
};
10321056

1033-
static struct platform_device *pdev;
1034-
10351057
static bool force;
1058+
#ifdef CONFIG_X86
10361059
module_param(force, bool, 0444);
10371060
MODULE_PARM_DESC(force, "Force device probe rather than using ACPI entry");
1061+
#endif
1062+
1063+
static int tpm_tis_force_device(void)
1064+
{
1065+
struct platform_device *pdev;
1066+
static const struct resource x86_resources[] = {
1067+
{
1068+
.start = 0xFED40000,
1069+
.end = 0xFED40000 + TIS_MEM_LEN - 1,
1070+
.flags = IORESOURCE_MEM,
1071+
},
1072+
};
1073+
1074+
if (!force)
1075+
return 0;
1076+
1077+
/* The driver core will match the name tpm_tis of the device to
1078+
* the tpm_tis platform driver and complete the setup via
1079+
* tpm_tis_plat_probe
1080+
*/
1081+
pdev = platform_device_register_simple("tpm_tis", -1, x86_resources,
1082+
ARRAY_SIZE(x86_resources));
1083+
if (IS_ERR(pdev))
1084+
return PTR_ERR(pdev);
1085+
force_pdev = pdev;
1086+
1087+
return 0;
1088+
}
1089+
10381090
static int __init init_tis(void)
10391091
{
10401092
int rc;
1041-
#ifdef CONFIG_PNP
1042-
if (!force) {
1043-
rc = pnp_register_driver(&tis_pnp_driver);
1044-
if (rc)
1045-
return rc;
1046-
}
1047-
#endif
1093+
1094+
rc = tpm_tis_force_device();
1095+
if (rc)
1096+
goto err_force;
1097+
1098+
rc = platform_driver_register(&tis_drv);
1099+
if (rc)
1100+
goto err_platform;
1101+
10481102
#ifdef CONFIG_ACPI
1049-
if (!force) {
1050-
rc = acpi_bus_register_driver(&tis_acpi_driver);
1051-
if (rc) {
1052-
#ifdef CONFIG_PNP
1053-
pnp_unregister_driver(&tis_pnp_driver);
1054-
#endif
1055-
return rc;
1056-
}
1057-
}
1103+
rc = acpi_bus_register_driver(&tis_acpi_driver);
1104+
if (rc)
1105+
goto err_acpi;
10581106
#endif
1059-
if (!force)
1060-
return 0;
10611107

1062-
rc = platform_driver_register(&tis_drv);
1063-
if (rc < 0)
1064-
return rc;
1065-
pdev = platform_device_register_simple("tpm_tis", -1, NULL, 0);
1066-
if (IS_ERR(pdev)) {
1067-
rc = PTR_ERR(pdev);
1068-
goto err_dev;
1108+
if (IS_ENABLED(CONFIG_PNP)) {
1109+
rc = pnp_register_driver(&tis_pnp_driver);
1110+
if (rc)
1111+
goto err_pnp;
10691112
}
1070-
rc = tpm_tis_init(&pdev->dev, &tis_default_info, NULL);
1071-
if (rc)
1072-
goto err_init;
1113+
10731114
return 0;
1074-
err_init:
1075-
platform_device_unregister(pdev);
1076-
err_dev:
1077-
platform_driver_unregister(&tis_drv);
1115+
1116+
err_pnp:
1117+
#ifdef CONFIG_ACPI
1118+
acpi_bus_unregister_driver(&tis_acpi_driver);
1119+
err_acpi:
1120+
#endif
1121+
platform_device_unregister(force_pdev);
1122+
err_platform:
1123+
if (force_pdev)
1124+
platform_device_unregister(force_pdev);
1125+
err_force:
10781126
return rc;
10791127
}
10801128

10811129
static void __exit cleanup_tis(void)
10821130
{
1083-
struct tpm_chip *chip;
1084-
#if defined(CONFIG_PNP) || defined(CONFIG_ACPI)
1085-
if (!force) {
1131+
pnp_unregister_driver(&tis_pnp_driver);
10861132
#ifdef CONFIG_ACPI
1087-
acpi_bus_unregister_driver(&tis_acpi_driver);
1088-
#endif
1089-
#ifdef CONFIG_PNP
1090-
pnp_unregister_driver(&tis_pnp_driver);
1091-
#endif
1092-
return;
1093-
}
1133+
acpi_bus_unregister_driver(&tis_acpi_driver);
10941134
#endif
1095-
chip = dev_get_drvdata(&pdev->dev);
1096-
tpm_chip_unregister(chip);
1097-
tpm_tis_remove(chip);
1098-
platform_device_unregister(pdev);
10991135
platform_driver_unregister(&tis_drv);
1136+
1137+
if (force_pdev)
1138+
platform_device_unregister(force_pdev);
11001139
}
11011140

11021141
module_init(init_tis);

0 commit comments

Comments
 (0)