c75c10ca2660365f7ddd6262aecb0eba1e27a092
[cascardo/linux.git] / drivers / char / tpm / tpm_infineon.c
1 /*
2  * Description:
3  * Device Driver for the Infineon Technologies
4  * SLD 9630 TT 1.1 and SLB 9635 TT 1.2 Trusted Platform Module
5  * Specifications at www.trustedcomputinggroup.org
6  *
7  * Copyright (C) 2005, Marcel Selhorst <tpmdd@selhorst.net>
8  * Sirrix AG - security technologies <tpmdd@sirrix.com> and
9  * Applied Data Security Group, Ruhr-University Bochum, Germany
10  * Project-Homepage: http://www.trust.rub.de/projects/linux-device-driver-infineon-tpm/ 
11  *
12  * This program is free software; you can redistribute it and/or
13  * modify it under the terms of the GNU General Public License as
14  * published by the Free Software Foundation, version 2 of the
15  * License.
16  */
17
18 #include <linux/init.h>
19 #include <linux/pnp.h>
20 #include "tpm.h"
21
22 /* Infineon specific definitions */
23 /* maximum number of WTX-packages */
24 #define TPM_MAX_WTX_PACKAGES    50
25 /* msleep-Time for WTX-packages */
26 #define TPM_WTX_MSLEEP_TIME     20
27 /* msleep-Time --> Interval to check status register */
28 #define TPM_MSLEEP_TIME         3
29 /* gives number of max. msleep()-calls before throwing timeout */
30 #define TPM_MAX_TRIES           5000
31 #define TPM_INFINEON_DEV_VEN_VALUE      0x15D1
32
33 #define TPM_INF_IO_PORT         0x0
34 #define TPM_INF_IO_MEM          0x1
35
36 #define TPM_INF_ADDR            0x0
37 #define TPM_INF_DATA            0x1
38
39 struct tpm_inf_dev {
40         int iotype;
41
42         void __iomem *mem_base; /* MMIO ioremap'd addr */
43         unsigned long map_base; /* phys MMIO base */
44         unsigned long map_size; /* MMIO region size */
45         unsigned int index_off; /* index register offset */
46
47         unsigned int data_regs; /* Data registers */
48         unsigned int data_size;
49
50         unsigned int config_port;       /* IO Port config index reg */
51         unsigned int config_size;
52 };
53
54 static struct tpm_inf_dev tpm_dev;
55
56 static inline void tpm_data_out(unsigned char data, unsigned char offset)
57 {
58         if (tpm_dev.iotype == TPM_INF_IO_PORT)
59                 outb(data, tpm_dev.data_regs + offset);
60         else
61                 writeb(data, tpm_dev.mem_base + tpm_dev.data_regs + offset);
62 }
63
64 static inline unsigned char tpm_data_in(unsigned char offset)
65 {
66         if (tpm_dev.iotype == TPM_INF_IO_PORT)
67                 return inb(tpm_dev.data_regs + offset);
68         else
69                 return readb(tpm_dev.mem_base + tpm_dev.data_regs + offset);
70 }
71
72 static inline void tpm_config_out(unsigned char data, unsigned char offset)
73 {
74         if (tpm_dev.iotype == TPM_INF_IO_PORT)
75                 outb(data, tpm_dev.config_port + offset);
76         else
77                 writeb(data, tpm_dev.mem_base + tpm_dev.index_off + offset);
78 }
79
80 static inline unsigned char tpm_config_in(unsigned char offset)
81 {
82         if (tpm_dev.iotype == TPM_INF_IO_PORT)
83                 return inb(tpm_dev.config_port + offset);
84         else
85                 return readb(tpm_dev.mem_base + tpm_dev.index_off + offset);
86 }
87
88 /* TPM header definitions */
89 enum infineon_tpm_header {
90         TPM_VL_VER = 0x01,
91         TPM_VL_CHANNEL_CONTROL = 0x07,
92         TPM_VL_CHANNEL_PERSONALISATION = 0x0A,
93         TPM_VL_CHANNEL_TPM = 0x0B,
94         TPM_VL_CONTROL = 0x00,
95         TPM_INF_NAK = 0x15,
96         TPM_CTRL_WTX = 0x10,
97         TPM_CTRL_WTX_ABORT = 0x18,
98         TPM_CTRL_WTX_ABORT_ACK = 0x18,
99         TPM_CTRL_ERROR = 0x20,
100         TPM_CTRL_CHAININGACK = 0x40,
101         TPM_CTRL_CHAINING = 0x80,
102         TPM_CTRL_DATA = 0x04,
103         TPM_CTRL_DATA_CHA = 0x84,
104         TPM_CTRL_DATA_CHA_ACK = 0xC4
105 };
106
107 enum infineon_tpm_register {
108         WRFIFO = 0x00,
109         RDFIFO = 0x01,
110         STAT = 0x02,
111         CMD = 0x03
112 };
113
114 enum infineon_tpm_command_bits {
115         CMD_DIS = 0x00,
116         CMD_LP = 0x01,
117         CMD_RES = 0x02,
118         CMD_IRQC = 0x06
119 };
120
121 enum infineon_tpm_status_bits {
122         STAT_XFE = 0x00,
123         STAT_LPA = 0x01,
124         STAT_FOK = 0x02,
125         STAT_TOK = 0x03,
126         STAT_IRQA = 0x06,
127         STAT_RDA = 0x07
128 };
129
130 /* some outgoing values */
131 enum infineon_tpm_values {
132         CHIP_ID1 = 0x20,
133         CHIP_ID2 = 0x21,
134         TPM_DAR = 0x30,
135         RESET_LP_IRQC_DISABLE = 0x41,
136         ENABLE_REGISTER_PAIR = 0x55,
137         IOLIMH = 0x60,
138         IOLIML = 0x61,
139         DISABLE_REGISTER_PAIR = 0xAA,
140         IDVENL = 0xF1,
141         IDVENH = 0xF2,
142         IDPDL = 0xF3,
143         IDPDH = 0xF4
144 };
145
146 static int number_of_wtx;
147
148 static int empty_fifo(struct tpm_chip *chip, int clear_wrfifo)
149 {
150         int status;
151         int check = 0;
152         int i;
153
154         if (clear_wrfifo) {
155                 for (i = 0; i < 4096; i++) {
156                         status = tpm_data_in(WRFIFO);
157                         if (status == 0xff) {
158                                 if (check == 5)
159                                         break;
160                                 else
161                                         check++;
162                         }
163                 }
164         }
165         /* Note: The values which are currently in the FIFO of the TPM
166            are thrown away since there is no usage for them. Usually,
167            this has nothing to say, since the TPM will give its answer
168            immediately or will be aborted anyway, so the data here is
169            usually garbage and useless.
170            We have to clean this, because the next communication with
171            the TPM would be rubbish, if there is still some old data
172            in the Read FIFO.
173          */
174         i = 0;
175         do {
176                 status = tpm_data_in(RDFIFO);
177                 status = tpm_data_in(STAT);
178                 i++;
179                 if (i == TPM_MAX_TRIES)
180                         return -EIO;
181         } while ((status & (1 << STAT_RDA)) != 0);
182         return 0;
183 }
184
185 static int wait(struct tpm_chip *chip, int wait_for_bit)
186 {
187         int status;
188         int i;
189         for (i = 0; i < TPM_MAX_TRIES; i++) {
190                 status = tpm_data_in(STAT);
191                 /* check the status-register if wait_for_bit is set */
192                 if (status & 1 << wait_for_bit)
193                         break;
194                 msleep(TPM_MSLEEP_TIME);
195         }
196         if (i == TPM_MAX_TRIES) {       /* timeout occurs */
197                 if (wait_for_bit == STAT_XFE)
198                         dev_err(chip->dev, "Timeout in wait(STAT_XFE)\n");
199                 if (wait_for_bit == STAT_RDA)
200                         dev_err(chip->dev, "Timeout in wait(STAT_RDA)\n");
201                 return -EIO;
202         }
203         return 0;
204 };
205
206 static void wait_and_send(struct tpm_chip *chip, u8 sendbyte)
207 {
208         wait(chip, STAT_XFE);
209         tpm_data_out(sendbyte, WRFIFO);
210 }
211
212     /* Note: WTX means Waiting-Time-Extension. Whenever the TPM needs more
213        calculation time, it sends a WTX-package, which has to be acknowledged
214        or aborted. This usually occurs if you are hammering the TPM with key
215        creation. Set the maximum number of WTX-packages in the definitions
216        above, if the number is reached, the waiting-time will be denied
217        and the TPM command has to be resend.
218      */
219
220 static void tpm_wtx(struct tpm_chip *chip)
221 {
222         number_of_wtx++;
223         dev_info(chip->dev, "Granting WTX (%02d / %02d)\n",
224                  number_of_wtx, TPM_MAX_WTX_PACKAGES);
225         wait_and_send(chip, TPM_VL_VER);
226         wait_and_send(chip, TPM_CTRL_WTX);
227         wait_and_send(chip, 0x00);
228         wait_and_send(chip, 0x00);
229         msleep(TPM_WTX_MSLEEP_TIME);
230 }
231
232 static void tpm_wtx_abort(struct tpm_chip *chip)
233 {
234         dev_info(chip->dev, "Aborting WTX\n");
235         wait_and_send(chip, TPM_VL_VER);
236         wait_and_send(chip, TPM_CTRL_WTX_ABORT);
237         wait_and_send(chip, 0x00);
238         wait_and_send(chip, 0x00);
239         number_of_wtx = 0;
240         msleep(TPM_WTX_MSLEEP_TIME);
241 }
242
243 static int tpm_inf_recv(struct tpm_chip *chip, u8 * buf, size_t count)
244 {
245         int i;
246         int ret;
247         u32 size = 0;
248         number_of_wtx = 0;
249
250 recv_begin:
251         /* start receiving header */
252         for (i = 0; i < 4; i++) {
253                 ret = wait(chip, STAT_RDA);
254                 if (ret)
255                         return -EIO;
256                 buf[i] = tpm_data_in(RDFIFO);
257         }
258
259         if (buf[0] != TPM_VL_VER) {
260                 dev_err(chip->dev,
261                         "Wrong transport protocol implementation!\n");
262                 return -EIO;
263         }
264
265         if (buf[1] == TPM_CTRL_DATA) {
266                 /* size of the data received */
267                 size = ((buf[2] << 8) | buf[3]);
268
269                 for (i = 0; i < size; i++) {
270                         wait(chip, STAT_RDA);
271                         buf[i] = tpm_data_in(RDFIFO);
272                 }
273
274                 if ((size == 0x6D00) && (buf[1] == 0x80)) {
275                         dev_err(chip->dev, "Error handling on vendor layer!\n");
276                         return -EIO;
277                 }
278
279                 for (i = 0; i < size; i++)
280                         buf[i] = buf[i + 6];
281
282                 size = size - 6;
283                 return size;
284         }
285
286         if (buf[1] == TPM_CTRL_WTX) {
287                 dev_info(chip->dev, "WTX-package received\n");
288                 if (number_of_wtx < TPM_MAX_WTX_PACKAGES) {
289                         tpm_wtx(chip);
290                         goto recv_begin;
291                 } else {
292                         tpm_wtx_abort(chip);
293                         goto recv_begin;
294                 }
295         }
296
297         if (buf[1] == TPM_CTRL_WTX_ABORT_ACK) {
298                 dev_info(chip->dev, "WTX-abort acknowledged\n");
299                 return size;
300         }
301
302         if (buf[1] == TPM_CTRL_ERROR) {
303                 dev_err(chip->dev, "ERROR-package received:\n");
304                 if (buf[4] == TPM_INF_NAK)
305                         dev_err(chip->dev,
306                                 "-> Negative acknowledgement"
307                                 " - retransmit command!\n");
308                 return -EIO;
309         }
310         return -EIO;
311 }
312
313 static int tpm_inf_send(struct tpm_chip *chip, u8 * buf, size_t count)
314 {
315         int i;
316         int ret;
317         u8 count_high, count_low, count_4, count_3, count_2, count_1;
318
319         /* Disabling Reset, LP and IRQC */
320         tpm_data_out(RESET_LP_IRQC_DISABLE, CMD);
321
322         ret = empty_fifo(chip, 1);
323         if (ret) {
324                 dev_err(chip->dev, "Timeout while clearing FIFO\n");
325                 return -EIO;
326         }
327
328         ret = wait(chip, STAT_XFE);
329         if (ret)
330                 return -EIO;
331
332         count_4 = (count & 0xff000000) >> 24;
333         count_3 = (count & 0x00ff0000) >> 16;
334         count_2 = (count & 0x0000ff00) >> 8;
335         count_1 = (count & 0x000000ff);
336         count_high = ((count + 6) & 0xffffff00) >> 8;
337         count_low = ((count + 6) & 0x000000ff);
338
339         /* Sending Header */
340         wait_and_send(chip, TPM_VL_VER);
341         wait_and_send(chip, TPM_CTRL_DATA);
342         wait_and_send(chip, count_high);
343         wait_and_send(chip, count_low);
344
345         /* Sending Data Header */
346         wait_and_send(chip, TPM_VL_VER);
347         wait_and_send(chip, TPM_VL_CHANNEL_TPM);
348         wait_and_send(chip, count_4);
349         wait_and_send(chip, count_3);
350         wait_and_send(chip, count_2);
351         wait_and_send(chip, count_1);
352
353         /* Sending Data */
354         for (i = 0; i < count; i++) {
355                 wait_and_send(chip, buf[i]);
356         }
357         return count;
358 }
359
360 static void tpm_inf_cancel(struct tpm_chip *chip)
361 {
362         /*
363            Since we are using the legacy mode to communicate
364            with the TPM, we have no cancel functions, but have
365            a workaround for interrupting the TPM through WTX.
366          */
367 }
368
369 static u8 tpm_inf_status(struct tpm_chip *chip)
370 {
371         return tpm_data_in(STAT);
372 }
373
374 static DEVICE_ATTR(pubek, S_IRUGO, tpm_show_pubek, NULL);
375 static DEVICE_ATTR(pcrs, S_IRUGO, tpm_show_pcrs, NULL);
376 static DEVICE_ATTR(caps, S_IRUGO, tpm_show_caps, NULL);
377 static DEVICE_ATTR(cancel, S_IWUSR | S_IWGRP, NULL, tpm_store_cancel);
378
379 static struct attribute *inf_attrs[] = {
380         &dev_attr_pubek.attr,
381         &dev_attr_pcrs.attr,
382         &dev_attr_caps.attr,
383         &dev_attr_cancel.attr,
384         NULL,
385 };
386
387 static struct attribute_group inf_attr_grp = {.attrs = inf_attrs };
388
389 static const struct tpm_vendor_specific tpm_inf = {
390         .recv = tpm_inf_recv,
391         .send = tpm_inf_send,
392         .cancel = tpm_inf_cancel,
393         .status = tpm_inf_status,
394         .req_complete_mask = 0,
395         .req_complete_val = 0,
396         .attr_group = &inf_attr_grp,
397 };
398
399 static const struct pnp_device_id tpm_inf_pnp_tbl[] = {
400         /* Infineon TPMs */
401         {"IFX0101", 0},
402         {"IFX0102", 0},
403         {"", 0}
404 };
405
406 MODULE_DEVICE_TABLE(pnp, tpm_inf_pnp_tbl);
407
408 static int tpm_inf_pnp_probe(struct pnp_dev *dev,
409                                        const struct pnp_device_id *dev_id)
410 {
411         int rc = 0;
412         u8 iol, ioh;
413         int vendorid[2];
414         int version[2];
415         int productid[2];
416         char chipname[20];
417         struct tpm_chip *chip;
418
419         /* read IO-ports through PnP */
420         if (pnp_port_valid(dev, 0) && pnp_port_valid(dev, 1) &&
421             !(pnp_port_flags(dev, 0) & IORESOURCE_DISABLED)) {
422
423                 tpm_dev.iotype = TPM_INF_IO_PORT;
424
425                 tpm_dev.config_port = pnp_port_start(dev, 0);
426                 tpm_dev.config_size = pnp_port_len(dev, 0);
427                 tpm_dev.data_regs = pnp_port_start(dev, 1);
428                 tpm_dev.data_size = pnp_port_len(dev, 1);
429                 if ((tpm_dev.data_size < 4) || (tpm_dev.config_size < 2)) {
430                         rc = -EINVAL;
431                         goto err_last;
432                 }
433                 dev_info(&dev->dev, "Found %s with ID %s\n",
434                          dev->name, dev_id->id);
435                 if (!((tpm_dev.data_regs >> 8) & 0xff)) {
436                         rc = -EINVAL;
437                         goto err_last;
438                 }
439                 /* publish my base address and request region */
440                 if (request_region(tpm_dev.data_regs, tpm_dev.data_size,
441                                    "tpm_infineon0") == NULL) {
442                         rc = -EINVAL;
443                         goto err_last;
444                 }
445                 if (request_region(tpm_dev.config_port, tpm_dev.config_size,
446                                    "tpm_infineon0") == NULL) {
447                         release_region(tpm_dev.data_regs, tpm_dev.data_size);
448                         rc = -EINVAL;
449                         goto err_last;
450                 }
451         } else if (pnp_mem_valid(dev, 0) &&
452                    !(pnp_mem_flags(dev, 0) & IORESOURCE_DISABLED)) {
453
454                 tpm_dev.iotype = TPM_INF_IO_MEM;
455
456                 tpm_dev.map_base = pnp_mem_start(dev, 0);
457                 tpm_dev.map_size = pnp_mem_len(dev, 0);
458
459                 dev_info(&dev->dev, "Found %s with ID %s\n",
460                          dev->name, dev_id->id);
461
462                 /* publish my base address and request region */
463                 if (request_mem_region(tpm_dev.map_base, tpm_dev.map_size,
464                                        "tpm_infineon0") == NULL) {
465                         rc = -EINVAL;
466                         goto err_last;
467                 }
468
469                 tpm_dev.mem_base = ioremap(tpm_dev.map_base, tpm_dev.map_size);
470                 if (tpm_dev.mem_base == NULL) {
471                         release_mem_region(tpm_dev.map_base, tpm_dev.map_size);
472                         rc = -EINVAL;
473                         goto err_last;
474                 }
475
476                 /*
477                  * The only known MMIO based Infineon TPM system provides
478                  * a single large mem region with the device config
479                  * registers at the default TPM_ADDR.  The data registers
480                  * seem like they could be placed anywhere within the MMIO
481                  * region, but lets just put them at zero offset.
482                  */
483                 tpm_dev.index_off = TPM_ADDR;
484                 tpm_dev.data_regs = 0x0;
485         } else {
486                 rc = -EINVAL;
487                 goto err_last;
488         }
489
490         /* query chip for its vendor, its version number a.s.o. */
491         tpm_config_out(ENABLE_REGISTER_PAIR, TPM_INF_ADDR);
492         tpm_config_out(IDVENL, TPM_INF_ADDR);
493         vendorid[1] = tpm_config_in(TPM_INF_DATA);
494         tpm_config_out(IDVENH, TPM_INF_ADDR);
495         vendorid[0] = tpm_config_in(TPM_INF_DATA);
496         tpm_config_out(IDPDL, TPM_INF_ADDR);
497         productid[1] = tpm_config_in(TPM_INF_DATA);
498         tpm_config_out(IDPDH, TPM_INF_ADDR);
499         productid[0] = tpm_config_in(TPM_INF_DATA);
500         tpm_config_out(CHIP_ID1, TPM_INF_ADDR);
501         version[1] = tpm_config_in(TPM_INF_DATA);
502         tpm_config_out(CHIP_ID2, TPM_INF_ADDR);
503         version[0] = tpm_config_in(TPM_INF_DATA);
504
505         switch ((productid[0] << 8) | productid[1]) {
506         case 6:
507                 snprintf(chipname, sizeof(chipname), " (SLD 9630 TT 1.1)");
508                 break;
509         case 11:
510                 snprintf(chipname, sizeof(chipname), " (SLB 9635 TT 1.2)");
511                 break;
512         default:
513                 snprintf(chipname, sizeof(chipname), " (unknown chip)");
514                 break;
515         }
516
517         if ((vendorid[0] << 8 | vendorid[1]) == (TPM_INFINEON_DEV_VEN_VALUE)) {
518
519                 /* configure TPM with IO-ports */
520                 tpm_config_out(IOLIMH, TPM_INF_ADDR);
521                 tpm_config_out((tpm_dev.data_regs >> 8) & 0xff, TPM_INF_DATA);
522                 tpm_config_out(IOLIML, TPM_INF_ADDR);
523                 tpm_config_out((tpm_dev.data_regs & 0xff), TPM_INF_DATA);
524
525                 /* control if IO-ports are set correctly */
526                 tpm_config_out(IOLIMH, TPM_INF_ADDR);
527                 ioh = tpm_config_in(TPM_INF_DATA);
528                 tpm_config_out(IOLIML, TPM_INF_ADDR);
529                 iol = tpm_config_in(TPM_INF_DATA);
530
531                 if ((ioh << 8 | iol) != tpm_dev.data_regs) {
532                         dev_err(&dev->dev,
533                                 "Could not set IO-data registers to 0x%x\n",
534                                 tpm_dev.data_regs);
535                         rc = -EIO;
536                         goto err_release_region;
537                 }
538
539                 /* activate register */
540                 tpm_config_out(TPM_DAR, TPM_INF_ADDR);
541                 tpm_config_out(0x01, TPM_INF_DATA);
542                 tpm_config_out(DISABLE_REGISTER_PAIR, TPM_INF_ADDR);
543
544                 /* disable RESET, LP and IRQC */
545                 tpm_data_out(RESET_LP_IRQC_DISABLE, CMD);
546
547                 /* Finally, we're done, print some infos */
548                 dev_info(&dev->dev, "TPM found: "
549                          "config base 0x%lx, "
550                          "data base 0x%lx, "
551                          "chip version 0x%02x%02x, "
552                          "vendor id 0x%x%x (Infineon), "
553                          "product id 0x%02x%02x"
554                          "%s\n",
555                          tpm_dev.iotype == TPM_INF_IO_PORT ?
556                          tpm_dev.config_port :
557                          tpm_dev.map_base + tpm_dev.index_off,
558                          tpm_dev.iotype == TPM_INF_IO_PORT ?
559                          tpm_dev.data_regs :
560                          tpm_dev.map_base + tpm_dev.data_regs,
561                          version[0], version[1],
562                          vendorid[0], vendorid[1],
563                          productid[0], productid[1], chipname);
564
565                 if (!(chip = tpm_register_hardware(&dev->dev, &tpm_inf)))
566                         goto err_release_region;
567
568                 return 0;
569         } else {
570                 rc = -ENODEV;
571                 goto err_release_region;
572         }
573
574 err_release_region:
575         if (tpm_dev.iotype == TPM_INF_IO_PORT) {
576                 release_region(tpm_dev.data_regs, tpm_dev.data_size);
577                 release_region(tpm_dev.config_port, tpm_dev.config_size);
578         } else {
579                 iounmap(tpm_dev.mem_base);
580                 release_mem_region(tpm_dev.map_base, tpm_dev.map_size);
581         }
582
583 err_last:
584         return rc;
585 }
586
587 static void tpm_inf_pnp_remove(struct pnp_dev *dev)
588 {
589         struct tpm_chip *chip = pnp_get_drvdata(dev);
590
591         if (chip) {
592                 if (tpm_dev.iotype == TPM_INF_IO_PORT) {
593                         release_region(tpm_dev.data_regs, tpm_dev.data_size);
594                         release_region(tpm_dev.config_port,
595                                        tpm_dev.config_size);
596                 } else {
597                         iounmap(tpm_dev.mem_base);
598                         release_mem_region(tpm_dev.map_base, tpm_dev.map_size);
599                 }
600                 tpm_dev_vendor_release(chip);
601                 tpm_remove_hardware(chip->dev);
602         }
603 }
604
605 static int tpm_inf_pnp_suspend(struct pnp_dev *dev, pm_message_t pm_state)
606 {
607         struct tpm_chip *chip = pnp_get_drvdata(dev);
608         int rc;
609         if (chip) {
610                 u8 savestate[] = {
611                         0, 193, /* TPM_TAG_RQU_COMMAND */
612                         0, 0, 0, 10,    /* blob length (in bytes) */
613                         0, 0, 0, 152    /* TPM_ORD_SaveState */
614                 };
615                 dev_info(&dev->dev, "saving TPM state\n");
616                 rc = tpm_inf_send(chip, savestate, sizeof(savestate));
617                 if (rc < 0) {
618                         dev_err(&dev->dev, "error while saving TPM state\n");
619                         return rc;
620                 }
621         }
622         return 0;
623 }
624
625 static int tpm_inf_pnp_resume(struct pnp_dev *dev)
626 {
627         /* Re-configure TPM after suspending */
628         tpm_config_out(ENABLE_REGISTER_PAIR, TPM_INF_ADDR);
629         tpm_config_out(IOLIMH, TPM_INF_ADDR);
630         tpm_config_out((tpm_dev.data_regs >> 8) & 0xff, TPM_INF_DATA);
631         tpm_config_out(IOLIML, TPM_INF_ADDR);
632         tpm_config_out((tpm_dev.data_regs & 0xff), TPM_INF_DATA);
633         /* activate register */
634         tpm_config_out(TPM_DAR, TPM_INF_ADDR);
635         tpm_config_out(0x01, TPM_INF_DATA);
636         tpm_config_out(DISABLE_REGISTER_PAIR, TPM_INF_ADDR);
637         /* disable RESET, LP and IRQC */
638         tpm_data_out(RESET_LP_IRQC_DISABLE, CMD);
639         return tpm_pm_resume(&dev->dev);
640 }
641
642 static struct pnp_driver tpm_inf_pnp_driver = {
643         .name = "tpm_inf_pnp",
644         .id_table = tpm_inf_pnp_tbl,
645         .probe = tpm_inf_pnp_probe,
646         .suspend = tpm_inf_pnp_suspend,
647         .resume = tpm_inf_pnp_resume,
648         .remove = tpm_inf_pnp_remove
649 };
650
651 static int __init init_inf(void)
652 {
653         return pnp_register_driver(&tpm_inf_pnp_driver);
654 }
655
656 static void __exit cleanup_inf(void)
657 {
658         pnp_unregister_driver(&tpm_inf_pnp_driver);
659 }
660
661 module_init(init_inf);
662 module_exit(cleanup_inf);
663
664 MODULE_AUTHOR("Marcel Selhorst <tpmdd@sirrix.com>");
665 MODULE_DESCRIPTION("Driver for Infineon TPM SLD 9630 TT 1.1 / SLB 9635 TT 1.2");
666 MODULE_VERSION("1.9.2");
667 MODULE_LICENSE("GPL");