Merge tag 'usb-4.8-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb
[cascardo/linux.git] / drivers / char / tpm / tpm_tis.c
1 /*
2  * Copyright (C) 2005, 2006 IBM Corporation
3  * Copyright (C) 2014, 2015 Intel Corporation
4  *
5  * Authors:
6  * Leendert van Doorn <leendert@watson.ibm.com>
7  * Kylene Hall <kjhall@us.ibm.com>
8  *
9  * Maintained by: <tpmdd-devel@lists.sourceforge.net>
10  *
11  * Device driver for TCG/TCPA TPM (trusted platform module).
12  * Specifications at www.trustedcomputinggroup.org
13  *
14  * This device driver implements the TPM interface as defined in
15  * the TCG TPM Interface Spec version 1.2, revision 1.0.
16  *
17  * This program is free software; you can redistribute it and/or
18  * modify it under the terms of the GNU General Public License as
19  * published by the Free Software Foundation, version 2 of the
20  * License.
21  */
22 #include <linux/init.h>
23 #include <linux/module.h>
24 #include <linux/moduleparam.h>
25 #include <linux/pnp.h>
26 #include <linux/slab.h>
27 #include <linux/interrupt.h>
28 #include <linux/wait.h>
29 #include <linux/acpi.h>
30 #include <linux/freezer.h>
31 #include "tpm.h"
32 #include "tpm_tis_core.h"
33
34 struct tpm_info {
35         struct resource res;
36         /* irq > 0 means: use irq $irq;
37          * irq = 0 means: autoprobe for an irq;
38          * irq = -1 means: no irq support
39          */
40         int irq;
41 };
42
43 struct tpm_tis_tcg_phy {
44         struct tpm_tis_data priv;
45         void __iomem *iobase;
46 };
47
48 static inline struct tpm_tis_tcg_phy *to_tpm_tis_tcg_phy(struct tpm_tis_data *data)
49 {
50         return container_of(data, struct tpm_tis_tcg_phy, priv);
51 }
52
53 static bool interrupts = true;
54 module_param(interrupts, bool, 0444);
55 MODULE_PARM_DESC(interrupts, "Enable interrupts");
56
57 static bool itpm;
58 module_param(itpm, bool, 0444);
59 MODULE_PARM_DESC(itpm, "Force iTPM workarounds (found on some Lenovo laptops)");
60
61 static bool force;
62 #ifdef CONFIG_X86
63 module_param(force, bool, 0444);
64 MODULE_PARM_DESC(force, "Force device probe rather than using ACPI entry");
65 #endif
66
67 #if defined(CONFIG_PNP) && defined(CONFIG_ACPI)
68 static int has_hid(struct acpi_device *dev, const char *hid)
69 {
70         struct acpi_hardware_id *id;
71
72         list_for_each_entry(id, &dev->pnp.ids, list)
73                 if (!strcmp(hid, id->id))
74                         return 1;
75
76         return 0;
77 }
78
79 static inline int is_itpm(struct acpi_device *dev)
80 {
81         return has_hid(dev, "INTC0102");
82 }
83 #else
84 static inline int is_itpm(struct acpi_device *dev)
85 {
86         return 0;
87 }
88 #endif
89
90 static int tpm_tcg_read_bytes(struct tpm_tis_data *data, u32 addr, u16 len,
91                               u8 *result)
92 {
93         struct tpm_tis_tcg_phy *phy = to_tpm_tis_tcg_phy(data);
94
95         while (len--)
96                 *result++ = ioread8(phy->iobase + addr);
97         return 0;
98 }
99
100 static int tpm_tcg_write_bytes(struct tpm_tis_data *data, u32 addr, u16 len,
101                                u8 *value)
102 {
103         struct tpm_tis_tcg_phy *phy = to_tpm_tis_tcg_phy(data);
104
105         while (len--)
106                 iowrite8(*value++, phy->iobase + addr);
107         return 0;
108 }
109
110 static int tpm_tcg_read16(struct tpm_tis_data *data, u32 addr, u16 *result)
111 {
112         struct tpm_tis_tcg_phy *phy = to_tpm_tis_tcg_phy(data);
113
114         *result = ioread16(phy->iobase + addr);
115         return 0;
116 }
117
118 static int tpm_tcg_read32(struct tpm_tis_data *data, u32 addr, u32 *result)
119 {
120         struct tpm_tis_tcg_phy *phy = to_tpm_tis_tcg_phy(data);
121
122         *result = ioread32(phy->iobase + addr);
123         return 0;
124 }
125
126 static int tpm_tcg_write32(struct tpm_tis_data *data, u32 addr, u32 value)
127 {
128         struct tpm_tis_tcg_phy *phy = to_tpm_tis_tcg_phy(data);
129
130         iowrite32(value, phy->iobase + addr);
131         return 0;
132 }
133
134 static const struct tpm_tis_phy_ops tpm_tcg = {
135         .read_bytes = tpm_tcg_read_bytes,
136         .write_bytes = tpm_tcg_write_bytes,
137         .read16 = tpm_tcg_read16,
138         .read32 = tpm_tcg_read32,
139         .write32 = tpm_tcg_write32,
140 };
141
142 static int tpm_tis_init(struct device *dev, struct tpm_info *tpm_info,
143                         acpi_handle acpi_dev_handle)
144 {
145         struct tpm_tis_tcg_phy *phy;
146         int irq = -1;
147
148         phy = devm_kzalloc(dev, sizeof(struct tpm_tis_tcg_phy), GFP_KERNEL);
149         if (phy == NULL)
150                 return -ENOMEM;
151
152         phy->iobase = devm_ioremap_resource(dev, &tpm_info->res);
153         if (IS_ERR(phy->iobase))
154                 return PTR_ERR(phy->iobase);
155
156         if (interrupts)
157                 irq = tpm_info->irq;
158
159         if (itpm)
160                 phy->priv.flags |= TPM_TIS_ITPM_POSSIBLE;
161
162         return tpm_tis_core_init(dev, &phy->priv, irq, &tpm_tcg,
163                                  acpi_dev_handle);
164 }
165
166 static SIMPLE_DEV_PM_OPS(tpm_tis_pm, tpm_pm_suspend, tpm_tis_resume);
167
168 static int tpm_tis_pnp_init(struct pnp_dev *pnp_dev,
169                             const struct pnp_device_id *pnp_id)
170 {
171         struct tpm_info tpm_info = {};
172         acpi_handle acpi_dev_handle = NULL;
173         struct resource *res;
174
175         res = pnp_get_resource(pnp_dev, IORESOURCE_MEM, 0);
176         if (!res)
177                 return -ENODEV;
178         tpm_info.res = *res;
179
180         if (pnp_irq_valid(pnp_dev, 0))
181                 tpm_info.irq = pnp_irq(pnp_dev, 0);
182         else
183                 tpm_info.irq = -1;
184
185         if (pnp_acpi_device(pnp_dev)) {
186                 if (is_itpm(pnp_acpi_device(pnp_dev)))
187                         itpm = true;
188
189                 acpi_dev_handle = ACPI_HANDLE(&pnp_dev->dev);
190         }
191
192         return tpm_tis_init(&pnp_dev->dev, &tpm_info, acpi_dev_handle);
193 }
194
195 static struct pnp_device_id tpm_pnp_tbl[] = {
196         {"PNP0C31", 0},         /* TPM */
197         {"ATM1200", 0},         /* Atmel */
198         {"IFX0102", 0},         /* Infineon */
199         {"BCM0101", 0},         /* Broadcom */
200         {"BCM0102", 0},         /* Broadcom */
201         {"NSC1200", 0},         /* National */
202         {"ICO0102", 0},         /* Intel */
203         /* Add new here */
204         {"", 0},                /* User Specified */
205         {"", 0}                 /* Terminator */
206 };
207 MODULE_DEVICE_TABLE(pnp, tpm_pnp_tbl);
208
209 static void tpm_tis_pnp_remove(struct pnp_dev *dev)
210 {
211         struct tpm_chip *chip = pnp_get_drvdata(dev);
212
213         tpm_chip_unregister(chip);
214         tpm_tis_remove(chip);
215 }
216
217 static struct pnp_driver tis_pnp_driver = {
218         .name = "tpm_tis",
219         .id_table = tpm_pnp_tbl,
220         .probe = tpm_tis_pnp_init,
221         .remove = tpm_tis_pnp_remove,
222         .driver = {
223                 .pm = &tpm_tis_pm,
224         },
225 };
226
227 #define TIS_HID_USR_IDX sizeof(tpm_pnp_tbl)/sizeof(struct pnp_device_id) -2
228 module_param_string(hid, tpm_pnp_tbl[TIS_HID_USR_IDX].id,
229                     sizeof(tpm_pnp_tbl[TIS_HID_USR_IDX].id), 0444);
230 MODULE_PARM_DESC(hid, "Set additional specific HID for this driver to probe");
231
232 #ifdef CONFIG_ACPI
233 static int tpm_check_resource(struct acpi_resource *ares, void *data)
234 {
235         struct tpm_info *tpm_info = (struct tpm_info *) data;
236         struct resource res;
237
238         if (acpi_dev_resource_interrupt(ares, 0, &res))
239                 tpm_info->irq = res.start;
240         else if (acpi_dev_resource_memory(ares, &res)) {
241                 tpm_info->res = res;
242                 tpm_info->res.name = NULL;
243         }
244
245         return 1;
246 }
247
248 static int tpm_tis_acpi_init(struct acpi_device *acpi_dev)
249 {
250         struct acpi_table_tpm2 *tbl;
251         acpi_status st;
252         struct list_head resources;
253         struct tpm_info tpm_info = {};
254         int ret;
255
256         st = acpi_get_table(ACPI_SIG_TPM2, 1,
257                             (struct acpi_table_header **) &tbl);
258         if (ACPI_FAILURE(st) || tbl->header.length < sizeof(*tbl)) {
259                 dev_err(&acpi_dev->dev,
260                         FW_BUG "failed to get TPM2 ACPI table\n");
261                 return -EINVAL;
262         }
263
264         if (tbl->start_method != ACPI_TPM2_MEMORY_MAPPED)
265                 return -ENODEV;
266
267         INIT_LIST_HEAD(&resources);
268         tpm_info.irq = -1;
269         ret = acpi_dev_get_resources(acpi_dev, &resources, tpm_check_resource,
270                                      &tpm_info);
271         if (ret < 0)
272                 return ret;
273
274         acpi_dev_free_resource_list(&resources);
275
276         if (resource_type(&tpm_info.res) != IORESOURCE_MEM) {
277                 dev_err(&acpi_dev->dev,
278                         FW_BUG "TPM2 ACPI table does not define a memory resource\n");
279                 return -EINVAL;
280         }
281
282         if (is_itpm(acpi_dev))
283                 itpm = true;
284
285         return tpm_tis_init(&acpi_dev->dev, &tpm_info, acpi_dev->handle);
286 }
287
288 static int tpm_tis_acpi_remove(struct acpi_device *dev)
289 {
290         struct tpm_chip *chip = dev_get_drvdata(&dev->dev);
291
292         tpm_chip_unregister(chip);
293         tpm_tis_remove(chip);
294
295         return 0;
296 }
297
298 static struct acpi_device_id tpm_acpi_tbl[] = {
299         {"MSFT0101", 0},        /* TPM 2.0 */
300         /* Add new here */
301         {"", 0},                /* User Specified */
302         {"", 0}                 /* Terminator */
303 };
304 MODULE_DEVICE_TABLE(acpi, tpm_acpi_tbl);
305
306 static struct acpi_driver tis_acpi_driver = {
307         .name = "tpm_tis",
308         .ids = tpm_acpi_tbl,
309         .ops = {
310                 .add = tpm_tis_acpi_init,
311                 .remove = tpm_tis_acpi_remove,
312         },
313         .drv = {
314                 .pm = &tpm_tis_pm,
315         },
316 };
317 #endif
318
319 static struct platform_device *force_pdev;
320
321 static int tpm_tis_plat_probe(struct platform_device *pdev)
322 {
323         struct tpm_info tpm_info = {};
324         struct resource *res;
325
326         res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
327         if (res == NULL) {
328                 dev_err(&pdev->dev, "no memory resource defined\n");
329                 return -ENODEV;
330         }
331         tpm_info.res = *res;
332
333         res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
334         if (res) {
335                 tpm_info.irq = res->start;
336         } else {
337                 if (pdev == force_pdev)
338                         tpm_info.irq = -1;
339                 else
340                         /* When forcing auto probe the IRQ */
341                         tpm_info.irq = 0;
342         }
343
344         return tpm_tis_init(&pdev->dev, &tpm_info, NULL);
345 }
346
347 static int tpm_tis_plat_remove(struct platform_device *pdev)
348 {
349         struct tpm_chip *chip = dev_get_drvdata(&pdev->dev);
350
351         tpm_chip_unregister(chip);
352         tpm_tis_remove(chip);
353
354         return 0;
355 }
356
357 static struct platform_driver tis_drv = {
358         .probe = tpm_tis_plat_probe,
359         .remove = tpm_tis_plat_remove,
360         .driver = {
361                 .name           = "tpm_tis",
362                 .pm             = &tpm_tis_pm,
363         },
364 };
365
366 static int tpm_tis_force_device(void)
367 {
368         struct platform_device *pdev;
369         static const struct resource x86_resources[] = {
370                 {
371                         .start = 0xFED40000,
372                         .end = 0xFED40000 + TIS_MEM_LEN - 1,
373                         .flags = IORESOURCE_MEM,
374                 },
375         };
376
377         if (!force)
378                 return 0;
379
380         /* The driver core will match the name tpm_tis of the device to
381          * the tpm_tis platform driver and complete the setup via
382          * tpm_tis_plat_probe
383          */
384         pdev = platform_device_register_simple("tpm_tis", -1, x86_resources,
385                                                ARRAY_SIZE(x86_resources));
386         if (IS_ERR(pdev))
387                 return PTR_ERR(pdev);
388         force_pdev = pdev;
389
390         return 0;
391 }
392
393 static int __init init_tis(void)
394 {
395         int rc;
396
397         rc = tpm_tis_force_device();
398         if (rc)
399                 goto err_force;
400
401         rc = platform_driver_register(&tis_drv);
402         if (rc)
403                 goto err_platform;
404
405 #ifdef CONFIG_ACPI
406         rc = acpi_bus_register_driver(&tis_acpi_driver);
407         if (rc)
408                 goto err_acpi;
409 #endif
410
411         if (IS_ENABLED(CONFIG_PNP)) {
412                 rc = pnp_register_driver(&tis_pnp_driver);
413                 if (rc)
414                         goto err_pnp;
415         }
416
417         return 0;
418
419 err_pnp:
420 #ifdef CONFIG_ACPI
421         acpi_bus_unregister_driver(&tis_acpi_driver);
422 err_acpi:
423 #endif
424         platform_device_unregister(force_pdev);
425 err_platform:
426         if (force_pdev)
427                 platform_device_unregister(force_pdev);
428 err_force:
429         return rc;
430 }
431
432 static void __exit cleanup_tis(void)
433 {
434         pnp_unregister_driver(&tis_pnp_driver);
435 #ifdef CONFIG_ACPI
436         acpi_bus_unregister_driver(&tis_acpi_driver);
437 #endif
438         platform_driver_unregister(&tis_drv);
439
440         if (force_pdev)
441                 platform_device_unregister(force_pdev);
442 }
443
444 module_init(init_tis);
445 module_exit(cleanup_tis);
446 MODULE_AUTHOR("Leendert van Doorn (leendert@watson.ibm.com)");
447 MODULE_DESCRIPTION("TPM Driver");
448 MODULE_VERSION("2.0");
449 MODULE_LICENSE("GPL");