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