diff options
-rw-r--r-- | drivers/char/tpm/tpm-chip.c | 4 | ||||
-rw-r--r-- | drivers/char/tpm/tpm.h | 17 | ||||
-rw-r--r-- | drivers/char/tpm/tpm_ppi.c | 141 | ||||
-rw-r--r-- | drivers/char/tpm/tpm_tis.c | 14 |
4 files changed, 112 insertions, 64 deletions
diff --git a/drivers/char/tpm/tpm-chip.c b/drivers/char/tpm/tpm-chip.c index 7dc9999e2d54..64102de91ca3 100644 --- a/drivers/char/tpm/tpm-chip.c +++ b/drivers/char/tpm/tpm-chip.c | |||
@@ -147,7 +147,7 @@ int tpm_chip_register(struct tpm_chip *chip) | |||
147 | if (rc) | 147 | if (rc) |
148 | goto del_misc; | 148 | goto del_misc; |
149 | 149 | ||
150 | rc = tpm_add_ppi(&chip->dev->kobj); | 150 | rc = tpm_add_ppi(chip); |
151 | if (rc) | 151 | if (rc) |
152 | goto del_sysfs; | 152 | goto del_sysfs; |
153 | 153 | ||
@@ -191,7 +191,7 @@ void tpm_chip_unregister(struct tpm_chip *chip) | |||
191 | 191 | ||
192 | if (chip->bios_dir) | 192 | if (chip->bios_dir) |
193 | tpm_bios_log_teardown(chip->bios_dir); | 193 | tpm_bios_log_teardown(chip->bios_dir); |
194 | tpm_remove_ppi(&chip->dev->kobj); | 194 | tpm_remove_ppi(chip); |
195 | tpm_sysfs_del_device(chip); | 195 | tpm_sysfs_del_device(chip); |
196 | 196 | ||
197 | tpm_dev_del_device(chip); | 197 | tpm_dev_del_device(chip); |
diff --git a/drivers/char/tpm/tpm.h b/drivers/char/tpm/tpm.h index 72ff18c872d3..3409acf953f3 100644 --- a/drivers/char/tpm/tpm.h +++ b/drivers/char/tpm/tpm.h | |||
@@ -27,6 +27,7 @@ | |||
27 | #include <linux/platform_device.h> | 27 | #include <linux/platform_device.h> |
28 | #include <linux/io.h> | 28 | #include <linux/io.h> |
29 | #include <linux/tpm.h> | 29 | #include <linux/tpm.h> |
30 | #include <linux/acpi.h> | ||
30 | 31 | ||
31 | enum tpm_const { | 32 | enum tpm_const { |
32 | TPM_MINOR = 224, /* officially assigned */ | 33 | TPM_MINOR = 224, /* officially assigned */ |
@@ -94,8 +95,11 @@ struct tpm_vendor_specific { | |||
94 | #define TPM_VID_WINBOND 0x1050 | 95 | #define TPM_VID_WINBOND 0x1050 |
95 | #define TPM_VID_STM 0x104A | 96 | #define TPM_VID_STM 0x104A |
96 | 97 | ||
98 | #define TPM_PPI_VERSION_LEN 3 | ||
99 | |||
97 | enum tpm_chip_flags { | 100 | enum tpm_chip_flags { |
98 | TPM_CHIP_FLAG_REGISTERED = BIT(0), | 101 | TPM_CHIP_FLAG_REGISTERED = BIT(0), |
102 | TPM_CHIP_FLAG_PPI = BIT(1), | ||
99 | }; | 103 | }; |
100 | 104 | ||
101 | struct tpm_chip { | 105 | struct tpm_chip { |
@@ -114,6 +118,11 @@ struct tpm_chip { | |||
114 | 118 | ||
115 | struct dentry **bios_dir; | 119 | struct dentry **bios_dir; |
116 | 120 | ||
121 | #ifdef CONFIG_ACPI | ||
122 | acpi_handle acpi_dev_handle; | ||
123 | char ppi_version[TPM_PPI_VERSION_LEN + 1]; | ||
124 | #endif /* CONFIG_ACPI */ | ||
125 | |||
117 | struct list_head list; | 126 | struct list_head list; |
118 | }; | 127 | }; |
119 | 128 | ||
@@ -345,15 +354,15 @@ void tpm_sysfs_del_device(struct tpm_chip *chip); | |||
345 | int tpm_pcr_read_dev(struct tpm_chip *chip, int pcr_idx, u8 *res_buf); | 354 | int tpm_pcr_read_dev(struct tpm_chip *chip, int pcr_idx, u8 *res_buf); |
346 | 355 | ||
347 | #ifdef CONFIG_ACPI | 356 | #ifdef CONFIG_ACPI |
348 | extern int tpm_add_ppi(struct kobject *); | 357 | extern int tpm_add_ppi(struct tpm_chip *chip); |
349 | extern void tpm_remove_ppi(struct kobject *); | 358 | extern void tpm_remove_ppi(struct tpm_chip *chip); |
350 | #else | 359 | #else |
351 | static inline int tpm_add_ppi(struct kobject *parent) | 360 | static inline int tpm_add_ppi(struct tpm_chip *chip) |
352 | { | 361 | { |
353 | return 0; | 362 | return 0; |
354 | } | 363 | } |
355 | 364 | ||
356 | static inline void tpm_remove_ppi(struct kobject *parent) | 365 | static inline void tpm_remove_ppi(struct tpm_chip *chip) |
357 | { | 366 | { |
358 | } | 367 | } |
359 | #endif | 368 | #endif |
diff --git a/drivers/char/tpm/tpm_ppi.c b/drivers/char/tpm/tpm_ppi.c index 61dcc8011ec7..af48c56f642f 100644 --- a/drivers/char/tpm/tpm_ppi.c +++ b/drivers/char/tpm/tpm_ppi.c | |||
@@ -1,3 +1,22 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2012-2014 Intel Corporation | ||
3 | * | ||
4 | * Authors: | ||
5 | * Xiaoyan Zhang <xiaoyan.zhang@intel.com> | ||
6 | * Jiang Liu <jiang.liu@linux.intel.com> | ||
7 | * Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com> | ||
8 | * | ||
9 | * Maintained by: <tpmdd-devel@lists.sourceforge.net> | ||
10 | * | ||
11 | * This file contains implementation of the sysfs interface for PPI. | ||
12 | * | ||
13 | * This program is free software; you can redistribute it and/or | ||
14 | * modify it under the terms of the GNU General Public License | ||
15 | * as published by the Free Software Foundation; version 2 | ||
16 | * of the License. | ||
17 | */ | ||
18 | |||
19 | |||
1 | #include <linux/acpi.h> | 20 | #include <linux/acpi.h> |
2 | #include "tpm.h" | 21 | #include "tpm.h" |
3 | 22 | ||
@@ -12,7 +31,6 @@ | |||
12 | #define PPI_TPM_REQ_MAX 22 | 31 | #define PPI_TPM_REQ_MAX 22 |
13 | #define PPI_VS_REQ_START 128 | 32 | #define PPI_VS_REQ_START 128 |
14 | #define PPI_VS_REQ_END 255 | 33 | #define PPI_VS_REQ_END 255 |
15 | #define PPI_VERSION_LEN 3 | ||
16 | 34 | ||
17 | static const u8 tpm_ppi_uuid[] = { | 35 | static const u8 tpm_ppi_uuid[] = { |
18 | 0xA6, 0xFA, 0xDD, 0x3D, | 36 | 0xA6, 0xFA, 0xDD, 0x3D, |
@@ -22,45 +40,22 @@ static const u8 tpm_ppi_uuid[] = { | |||
22 | 0x8D, 0x10, 0x08, 0x9D, 0x16, 0x53 | 40 | 0x8D, 0x10, 0x08, 0x9D, 0x16, 0x53 |
23 | }; | 41 | }; |
24 | 42 | ||
25 | static char tpm_ppi_version[PPI_VERSION_LEN + 1]; | ||
26 | static acpi_handle tpm_ppi_handle; | ||
27 | |||
28 | static acpi_status ppi_callback(acpi_handle handle, u32 level, void *context, | ||
29 | void **return_value) | ||
30 | { | ||
31 | union acpi_object *obj; | ||
32 | |||
33 | if (!acpi_check_dsm(handle, tpm_ppi_uuid, TPM_PPI_REVISION_ID, | ||
34 | 1 << TPM_PPI_FN_VERSION)) | ||
35 | return AE_OK; | ||
36 | |||
37 | /* Cache version string */ | ||
38 | obj = acpi_evaluate_dsm_typed(handle, tpm_ppi_uuid, | ||
39 | TPM_PPI_REVISION_ID, TPM_PPI_FN_VERSION, | ||
40 | NULL, ACPI_TYPE_STRING); | ||
41 | if (obj) { | ||
42 | strlcpy(tpm_ppi_version, obj->string.pointer, | ||
43 | PPI_VERSION_LEN + 1); | ||
44 | ACPI_FREE(obj); | ||
45 | } | ||
46 | |||
47 | *return_value = handle; | ||
48 | |||
49 | return AE_CTRL_TERMINATE; | ||
50 | } | ||
51 | |||
52 | static inline union acpi_object * | 43 | static inline union acpi_object * |
53 | tpm_eval_dsm(int func, acpi_object_type type, union acpi_object *argv4) | 44 | tpm_eval_dsm(acpi_handle ppi_handle, int func, acpi_object_type type, |
45 | union acpi_object *argv4) | ||
54 | { | 46 | { |
55 | BUG_ON(!tpm_ppi_handle); | 47 | BUG_ON(!ppi_handle); |
56 | return acpi_evaluate_dsm_typed(tpm_ppi_handle, tpm_ppi_uuid, | 48 | return acpi_evaluate_dsm_typed(ppi_handle, tpm_ppi_uuid, |
57 | TPM_PPI_REVISION_ID, func, argv4, type); | 49 | TPM_PPI_REVISION_ID, |
50 | func, argv4, type); | ||
58 | } | 51 | } |
59 | 52 | ||
60 | static ssize_t tpm_show_ppi_version(struct device *dev, | 53 | static ssize_t tpm_show_ppi_version(struct device *dev, |
61 | struct device_attribute *attr, char *buf) | 54 | struct device_attribute *attr, char *buf) |
62 | { | 55 | { |
63 | return scnprintf(buf, PAGE_SIZE, "%s\n", tpm_ppi_version); | 56 | struct tpm_chip *chip = dev_get_drvdata(dev); |
57 | |||
58 | return scnprintf(buf, PAGE_SIZE, "%s\n", chip->ppi_version); | ||
64 | } | 59 | } |
65 | 60 | ||
66 | static ssize_t tpm_show_ppi_request(struct device *dev, | 61 | static ssize_t tpm_show_ppi_request(struct device *dev, |
@@ -68,8 +63,10 @@ static ssize_t tpm_show_ppi_request(struct device *dev, | |||
68 | { | 63 | { |
69 | ssize_t size = -EINVAL; | 64 | ssize_t size = -EINVAL; |
70 | union acpi_object *obj; | 65 | union acpi_object *obj; |
66 | struct tpm_chip *chip = dev_get_drvdata(dev); | ||
71 | 67 | ||
72 | obj = tpm_eval_dsm(TPM_PPI_FN_GETREQ, ACPI_TYPE_PACKAGE, NULL); | 68 | obj = tpm_eval_dsm(chip->acpi_dev_handle, TPM_PPI_FN_GETREQ, |
69 | ACPI_TYPE_PACKAGE, NULL); | ||
73 | if (!obj) | 70 | if (!obj) |
74 | return -ENXIO; | 71 | return -ENXIO; |
75 | 72 | ||
@@ -103,14 +100,15 @@ static ssize_t tpm_store_ppi_request(struct device *dev, | |||
103 | int func = TPM_PPI_FN_SUBREQ; | 100 | int func = TPM_PPI_FN_SUBREQ; |
104 | union acpi_object *obj, tmp; | 101 | union acpi_object *obj, tmp; |
105 | union acpi_object argv4 = ACPI_INIT_DSM_ARGV4(1, &tmp); | 102 | union acpi_object argv4 = ACPI_INIT_DSM_ARGV4(1, &tmp); |
103 | struct tpm_chip *chip = dev_get_drvdata(dev); | ||
106 | 104 | ||
107 | /* | 105 | /* |
108 | * the function to submit TPM operation request to pre-os environment | 106 | * the function to submit TPM operation request to pre-os environment |
109 | * is updated with function index from SUBREQ to SUBREQ2 since PPI | 107 | * is updated with function index from SUBREQ to SUBREQ2 since PPI |
110 | * version 1.1 | 108 | * version 1.1 |
111 | */ | 109 | */ |
112 | if (acpi_check_dsm(tpm_ppi_handle, tpm_ppi_uuid, TPM_PPI_REVISION_ID, | 110 | if (acpi_check_dsm(chip->acpi_dev_handle, tpm_ppi_uuid, |
113 | 1 << TPM_PPI_FN_SUBREQ2)) | 111 | TPM_PPI_REVISION_ID, 1 << TPM_PPI_FN_SUBREQ2)) |
114 | func = TPM_PPI_FN_SUBREQ2; | 112 | func = TPM_PPI_FN_SUBREQ2; |
115 | 113 | ||
116 | /* | 114 | /* |
@@ -119,7 +117,7 @@ static ssize_t tpm_store_ppi_request(struct device *dev, | |||
119 | * string/package type. For PPI version 1.0 and 1.1, use buffer type | 117 | * string/package type. For PPI version 1.0 and 1.1, use buffer type |
120 | * for compatibility, and use package type since 1.2 according to spec. | 118 | * for compatibility, and use package type since 1.2 according to spec. |
121 | */ | 119 | */ |
122 | if (strcmp(tpm_ppi_version, "1.2") < 0) { | 120 | if (strcmp(chip->ppi_version, "1.2") < 0) { |
123 | if (sscanf(buf, "%d", &req) != 1) | 121 | if (sscanf(buf, "%d", &req) != 1) |
124 | return -EINVAL; | 122 | return -EINVAL; |
125 | argv4.type = ACPI_TYPE_BUFFER; | 123 | argv4.type = ACPI_TYPE_BUFFER; |
@@ -131,7 +129,8 @@ static ssize_t tpm_store_ppi_request(struct device *dev, | |||
131 | return -EINVAL; | 129 | return -EINVAL; |
132 | } | 130 | } |
133 | 131 | ||
134 | obj = tpm_eval_dsm(func, ACPI_TYPE_INTEGER, &argv4); | 132 | obj = tpm_eval_dsm(chip->acpi_dev_handle, func, ACPI_TYPE_INTEGER, |
133 | &argv4); | ||
135 | if (!obj) { | 134 | if (!obj) { |
136 | return -ENXIO; | 135 | return -ENXIO; |
137 | } else { | 136 | } else { |
@@ -157,6 +156,7 @@ static ssize_t tpm_show_ppi_transition_action(struct device *dev, | |||
157 | .buffer.length = 0, | 156 | .buffer.length = 0, |
158 | .buffer.pointer = NULL | 157 | .buffer.pointer = NULL |
159 | }; | 158 | }; |
159 | struct tpm_chip *chip = dev_get_drvdata(dev); | ||
160 | 160 | ||
161 | static char *info[] = { | 161 | static char *info[] = { |
162 | "None", | 162 | "None", |
@@ -171,9 +171,10 @@ static ssize_t tpm_show_ppi_transition_action(struct device *dev, | |||
171 | * (e.g. Capella with PPI 1.0) need integer/string/buffer type, so for | 171 | * (e.g. Capella with PPI 1.0) need integer/string/buffer type, so for |
172 | * compatibility, define params[3].type as buffer, if PPI version < 1.2 | 172 | * compatibility, define params[3].type as buffer, if PPI version < 1.2 |
173 | */ | 173 | */ |
174 | if (strcmp(tpm_ppi_version, "1.2") < 0) | 174 | if (strcmp(chip->ppi_version, "1.2") < 0) |
175 | obj = &tmp; | 175 | obj = &tmp; |
176 | obj = tpm_eval_dsm(TPM_PPI_FN_GETACT, ACPI_TYPE_INTEGER, obj); | 176 | obj = tpm_eval_dsm(chip->acpi_dev_handle, TPM_PPI_FN_GETACT, |
177 | ACPI_TYPE_INTEGER, obj); | ||
177 | if (!obj) { | 178 | if (!obj) { |
178 | return -ENXIO; | 179 | return -ENXIO; |
179 | } else { | 180 | } else { |
@@ -196,8 +197,10 @@ static ssize_t tpm_show_ppi_response(struct device *dev, | |||
196 | acpi_status status = -EINVAL; | 197 | acpi_status status = -EINVAL; |
197 | union acpi_object *obj, *ret_obj; | 198 | union acpi_object *obj, *ret_obj; |
198 | u64 req, res; | 199 | u64 req, res; |
200 | struct tpm_chip *chip = dev_get_drvdata(dev); | ||
199 | 201 | ||
200 | obj = tpm_eval_dsm(TPM_PPI_FN_GETRSP, ACPI_TYPE_PACKAGE, NULL); | 202 | obj = tpm_eval_dsm(chip->acpi_dev_handle, TPM_PPI_FN_GETRSP, |
203 | ACPI_TYPE_PACKAGE, NULL); | ||
201 | if (!obj) | 204 | if (!obj) |
202 | return -ENXIO; | 205 | return -ENXIO; |
203 | 206 | ||
@@ -248,7 +251,8 @@ cleanup: | |||
248 | return status; | 251 | return status; |
249 | } | 252 | } |
250 | 253 | ||
251 | static ssize_t show_ppi_operations(char *buf, u32 start, u32 end) | 254 | static ssize_t show_ppi_operations(acpi_handle dev_handle, char *buf, u32 start, |
255 | u32 end) | ||
252 | { | 256 | { |
253 | int i; | 257 | int i; |
254 | u32 ret; | 258 | u32 ret; |
@@ -264,14 +268,15 @@ static ssize_t show_ppi_operations(char *buf, u32 start, u32 end) | |||
264 | "User not required", | 268 | "User not required", |
265 | }; | 269 | }; |
266 | 270 | ||
267 | if (!acpi_check_dsm(tpm_ppi_handle, tpm_ppi_uuid, TPM_PPI_REVISION_ID, | 271 | if (!acpi_check_dsm(dev_handle, tpm_ppi_uuid, TPM_PPI_REVISION_ID, |
268 | 1 << TPM_PPI_FN_GETOPR)) | 272 | 1 << TPM_PPI_FN_GETOPR)) |
269 | return -EPERM; | 273 | return -EPERM; |
270 | 274 | ||
271 | tmp.integer.type = ACPI_TYPE_INTEGER; | 275 | tmp.integer.type = ACPI_TYPE_INTEGER; |
272 | for (i = start; i <= end; i++) { | 276 | for (i = start; i <= end; i++) { |
273 | tmp.integer.value = i; | 277 | tmp.integer.value = i; |
274 | obj = tpm_eval_dsm(TPM_PPI_FN_GETOPR, ACPI_TYPE_INTEGER, &argv); | 278 | obj = tpm_eval_dsm(dev_handle, TPM_PPI_FN_GETOPR, |
279 | ACPI_TYPE_INTEGER, &argv); | ||
275 | if (!obj) { | 280 | if (!obj) { |
276 | return -ENOMEM; | 281 | return -ENOMEM; |
277 | } else { | 282 | } else { |
@@ -291,14 +296,20 @@ static ssize_t tpm_show_ppi_tcg_operations(struct device *dev, | |||
291 | struct device_attribute *attr, | 296 | struct device_attribute *attr, |
292 | char *buf) | 297 | char *buf) |
293 | { | 298 | { |
294 | return show_ppi_operations(buf, 0, PPI_TPM_REQ_MAX); | 299 | struct tpm_chip *chip = dev_get_drvdata(dev); |
300 | |||
301 | return show_ppi_operations(chip->acpi_dev_handle, buf, 0, | ||
302 | PPI_TPM_REQ_MAX); | ||
295 | } | 303 | } |
296 | 304 | ||
297 | static ssize_t tpm_show_ppi_vs_operations(struct device *dev, | 305 | static ssize_t tpm_show_ppi_vs_operations(struct device *dev, |
298 | struct device_attribute *attr, | 306 | struct device_attribute *attr, |
299 | char *buf) | 307 | char *buf) |
300 | { | 308 | { |
301 | return show_ppi_operations(buf, PPI_VS_REQ_START, PPI_VS_REQ_END); | 309 | struct tpm_chip *chip = dev_get_drvdata(dev); |
310 | |||
311 | return show_ppi_operations(chip->acpi_dev_handle, buf, PPI_VS_REQ_START, | ||
312 | PPI_VS_REQ_END); | ||
302 | } | 313 | } |
303 | 314 | ||
304 | static DEVICE_ATTR(version, S_IRUGO, tpm_show_ppi_version, NULL); | 315 | static DEVICE_ATTR(version, S_IRUGO, tpm_show_ppi_version, NULL); |
@@ -323,16 +334,38 @@ static struct attribute_group ppi_attr_grp = { | |||
323 | .attrs = ppi_attrs | 334 | .attrs = ppi_attrs |
324 | }; | 335 | }; |
325 | 336 | ||
326 | int tpm_add_ppi(struct kobject *parent) | 337 | int tpm_add_ppi(struct tpm_chip *chip) |
327 | { | 338 | { |
328 | /* Cache TPM ACPI handle and version string */ | 339 | union acpi_object *obj; |
329 | acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX, | 340 | int rc; |
330 | ppi_callback, NULL, NULL, &tpm_ppi_handle); | 341 | |
331 | return tpm_ppi_handle ? sysfs_create_group(parent, &ppi_attr_grp) : 0; | 342 | if (!chip->acpi_dev_handle) |
343 | return 0; | ||
344 | |||
345 | if (!acpi_check_dsm(chip->acpi_dev_handle, tpm_ppi_uuid, | ||
346 | TPM_PPI_REVISION_ID, 1 << TPM_PPI_FN_VERSION)) | ||
347 | return 0; | ||
348 | |||
349 | /* Cache PPI version string. */ | ||
350 | obj = acpi_evaluate_dsm_typed(chip->acpi_dev_handle, tpm_ppi_uuid, | ||
351 | TPM_PPI_REVISION_ID, TPM_PPI_FN_VERSION, | ||
352 | NULL, ACPI_TYPE_STRING); | ||
353 | if (obj) { | ||
354 | strlcpy(chip->ppi_version, obj->string.pointer, | ||
355 | sizeof(chip->ppi_version)); | ||
356 | ACPI_FREE(obj); | ||
357 | } | ||
358 | |||
359 | rc = sysfs_create_group(&chip->dev->kobj, &ppi_attr_grp); | ||
360 | |||
361 | if (!rc) | ||
362 | chip->flags |= TPM_CHIP_FLAG_PPI; | ||
363 | |||
364 | return rc; | ||
332 | } | 365 | } |
333 | 366 | ||
334 | void tpm_remove_ppi(struct kobject *parent) | 367 | void tpm_remove_ppi(struct tpm_chip *chip) |
335 | { | 368 | { |
336 | if (tpm_ppi_handle) | 369 | if (chip->flags & TPM_CHIP_FLAG_PPI) |
337 | sysfs_remove_group(parent, &ppi_attr_grp); | 370 | sysfs_remove_group(&chip->dev->kobj, &ppi_attr_grp); |
338 | } | 371 | } |
diff --git a/drivers/char/tpm/tpm_tis.c b/drivers/char/tpm/tpm_tis.c index 36f4fec11c2a..9695850d2afa 100644 --- a/drivers/char/tpm/tpm_tis.c +++ b/drivers/char/tpm/tpm_tis.c | |||
@@ -580,8 +580,9 @@ static void tpm_tis_remove(struct tpm_chip *chip) | |||
580 | release_locality(chip, chip->vendor.locality, 1); | 580 | release_locality(chip, chip->vendor.locality, 1); |
581 | } | 581 | } |
582 | 582 | ||
583 | static int tpm_tis_init(struct device *dev, resource_size_t start, | 583 | static int tpm_tis_init(struct device *dev, acpi_handle acpi_dev_handle, |
584 | resource_size_t len, unsigned int irq) | 584 | resource_size_t start, resource_size_t len, |
585 | unsigned int irq) | ||
585 | { | 586 | { |
586 | u32 vendor, intfcaps, intmask; | 587 | u32 vendor, intfcaps, intmask; |
587 | int rc, i, irq_s, irq_e, probe; | 588 | int rc, i, irq_s, irq_e, probe; |
@@ -597,6 +598,7 @@ static int tpm_tis_init(struct device *dev, resource_size_t start, | |||
597 | return PTR_ERR(chip); | 598 | return PTR_ERR(chip); |
598 | 599 | ||
599 | chip->vendor.priv = priv; | 600 | chip->vendor.priv = priv; |
601 | chip->acpi_dev_handle = acpi_dev_handle; | ||
600 | 602 | ||
601 | chip->vendor.iobase = devm_ioremap(dev, start, len); | 603 | chip->vendor.iobase = devm_ioremap(dev, start, len); |
602 | if (!chip->vendor.iobase) | 604 | if (!chip->vendor.iobase) |
@@ -827,6 +829,7 @@ static int tpm_tis_pnp_init(struct pnp_dev *pnp_dev, | |||
827 | { | 829 | { |
828 | resource_size_t start, len; | 830 | resource_size_t start, len; |
829 | unsigned int irq = 0; | 831 | unsigned int irq = 0; |
832 | acpi_handle acpi_dev_handle = NULL; | ||
830 | 833 | ||
831 | start = pnp_mem_start(pnp_dev, 0); | 834 | start = pnp_mem_start(pnp_dev, 0); |
832 | len = pnp_mem_len(pnp_dev, 0); | 835 | len = pnp_mem_len(pnp_dev, 0); |
@@ -839,7 +842,10 @@ static int tpm_tis_pnp_init(struct pnp_dev *pnp_dev, | |||
839 | if (is_itpm(pnp_dev)) | 842 | if (is_itpm(pnp_dev)) |
840 | itpm = true; | 843 | itpm = true; |
841 | 844 | ||
842 | return tpm_tis_init(&pnp_dev->dev, start, len, irq); | 845 | if (pnp_acpi_device(pnp_dev)) |
846 | acpi_dev_handle = pnp_acpi_device(pnp_dev)->handle; | ||
847 | |||
848 | return tpm_tis_init(&pnp_dev->dev, acpi_dev_handle, start, len, irq); | ||
843 | } | 849 | } |
844 | 850 | ||
845 | static struct pnp_device_id tpm_pnp_tbl[] = { | 851 | static struct pnp_device_id tpm_pnp_tbl[] = { |
@@ -907,7 +913,7 @@ static int __init init_tis(void) | |||
907 | rc = PTR_ERR(pdev); | 913 | rc = PTR_ERR(pdev); |
908 | goto err_dev; | 914 | goto err_dev; |
909 | } | 915 | } |
910 | rc = tpm_tis_init(&pdev->dev, TIS_MEM_BASE, TIS_MEM_LEN, 0); | 916 | rc = tpm_tis_init(&pdev->dev, NULL, TIS_MEM_BASE, TIS_MEM_LEN, 0); |
911 | if (rc) | 917 | if (rc) |
912 | goto err_init; | 918 | goto err_init; |
913 | return 0; | 919 | return 0; |