xref: /openbmc/linux/drivers/char/tpm/tpm_infineon.c (revision 12eb4683)
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 file_operations inf_ops = {
390 	.owner = THIS_MODULE,
391 	.llseek = no_llseek,
392 	.open = tpm_open,
393 	.read = tpm_read,
394 	.write = tpm_write,
395 	.release = tpm_release,
396 };
397 
398 static const struct tpm_vendor_specific tpm_inf = {
399 	.recv = tpm_inf_recv,
400 	.send = tpm_inf_send,
401 	.cancel = tpm_inf_cancel,
402 	.status = tpm_inf_status,
403 	.req_complete_mask = 0,
404 	.req_complete_val = 0,
405 	.attr_group = &inf_attr_grp,
406 	.miscdev = {.fops = &inf_ops,},
407 };
408 
409 static const struct pnp_device_id tpm_inf_pnp_tbl[] = {
410 	/* Infineon TPMs */
411 	{"IFX0101", 0},
412 	{"IFX0102", 0},
413 	{"", 0}
414 };
415 
416 MODULE_DEVICE_TABLE(pnp, tpm_inf_pnp_tbl);
417 
418 static int tpm_inf_pnp_probe(struct pnp_dev *dev,
419 				       const struct pnp_device_id *dev_id)
420 {
421 	int rc = 0;
422 	u8 iol, ioh;
423 	int vendorid[2];
424 	int version[2];
425 	int productid[2];
426 	char chipname[20];
427 	struct tpm_chip *chip;
428 
429 	/* read IO-ports through PnP */
430 	if (pnp_port_valid(dev, 0) && pnp_port_valid(dev, 1) &&
431 	    !(pnp_port_flags(dev, 0) & IORESOURCE_DISABLED)) {
432 
433 		tpm_dev.iotype = TPM_INF_IO_PORT;
434 
435 		tpm_dev.config_port = pnp_port_start(dev, 0);
436 		tpm_dev.config_size = pnp_port_len(dev, 0);
437 		tpm_dev.data_regs = pnp_port_start(dev, 1);
438 		tpm_dev.data_size = pnp_port_len(dev, 1);
439 		if ((tpm_dev.data_size < 4) || (tpm_dev.config_size < 2)) {
440 			rc = -EINVAL;
441 			goto err_last;
442 		}
443 		dev_info(&dev->dev, "Found %s with ID %s\n",
444 			 dev->name, dev_id->id);
445 		if (!((tpm_dev.data_regs >> 8) & 0xff)) {
446 			rc = -EINVAL;
447 			goto err_last;
448 		}
449 		/* publish my base address and request region */
450 		if (request_region(tpm_dev.data_regs, tpm_dev.data_size,
451 				   "tpm_infineon0") == NULL) {
452 			rc = -EINVAL;
453 			goto err_last;
454 		}
455 		if (request_region(tpm_dev.config_port, tpm_dev.config_size,
456 				   "tpm_infineon0") == NULL) {
457 			release_region(tpm_dev.data_regs, tpm_dev.data_size);
458 			rc = -EINVAL;
459 			goto err_last;
460 		}
461 	} else if (pnp_mem_valid(dev, 0) &&
462 		   !(pnp_mem_flags(dev, 0) & IORESOURCE_DISABLED)) {
463 
464 		tpm_dev.iotype = TPM_INF_IO_MEM;
465 
466 		tpm_dev.map_base = pnp_mem_start(dev, 0);
467 		tpm_dev.map_size = pnp_mem_len(dev, 0);
468 
469 		dev_info(&dev->dev, "Found %s with ID %s\n",
470 			 dev->name, dev_id->id);
471 
472 		/* publish my base address and request region */
473 		if (request_mem_region(tpm_dev.map_base, tpm_dev.map_size,
474 				       "tpm_infineon0") == NULL) {
475 			rc = -EINVAL;
476 			goto err_last;
477 		}
478 
479 		tpm_dev.mem_base = ioremap(tpm_dev.map_base, tpm_dev.map_size);
480 		if (tpm_dev.mem_base == NULL) {
481 			release_mem_region(tpm_dev.map_base, tpm_dev.map_size);
482 			rc = -EINVAL;
483 			goto err_last;
484 		}
485 
486 		/*
487 		 * The only known MMIO based Infineon TPM system provides
488 		 * a single large mem region with the device config
489 		 * registers at the default TPM_ADDR.  The data registers
490 		 * seem like they could be placed anywhere within the MMIO
491 		 * region, but lets just put them at zero offset.
492 		 */
493 		tpm_dev.index_off = TPM_ADDR;
494 		tpm_dev.data_regs = 0x0;
495 	} else {
496 		rc = -EINVAL;
497 		goto err_last;
498 	}
499 
500 	/* query chip for its vendor, its version number a.s.o. */
501 	tpm_config_out(ENABLE_REGISTER_PAIR, TPM_INF_ADDR);
502 	tpm_config_out(IDVENL, TPM_INF_ADDR);
503 	vendorid[1] = tpm_config_in(TPM_INF_DATA);
504 	tpm_config_out(IDVENH, TPM_INF_ADDR);
505 	vendorid[0] = tpm_config_in(TPM_INF_DATA);
506 	tpm_config_out(IDPDL, TPM_INF_ADDR);
507 	productid[1] = tpm_config_in(TPM_INF_DATA);
508 	tpm_config_out(IDPDH, TPM_INF_ADDR);
509 	productid[0] = tpm_config_in(TPM_INF_DATA);
510 	tpm_config_out(CHIP_ID1, TPM_INF_ADDR);
511 	version[1] = tpm_config_in(TPM_INF_DATA);
512 	tpm_config_out(CHIP_ID2, TPM_INF_ADDR);
513 	version[0] = tpm_config_in(TPM_INF_DATA);
514 
515 	switch ((productid[0] << 8) | productid[1]) {
516 	case 6:
517 		snprintf(chipname, sizeof(chipname), " (SLD 9630 TT 1.1)");
518 		break;
519 	case 11:
520 		snprintf(chipname, sizeof(chipname), " (SLB 9635 TT 1.2)");
521 		break;
522 	default:
523 		snprintf(chipname, sizeof(chipname), " (unknown chip)");
524 		break;
525 	}
526 
527 	if ((vendorid[0] << 8 | vendorid[1]) == (TPM_INFINEON_DEV_VEN_VALUE)) {
528 
529 		/* configure TPM with IO-ports */
530 		tpm_config_out(IOLIMH, TPM_INF_ADDR);
531 		tpm_config_out((tpm_dev.data_regs >> 8) & 0xff, TPM_INF_DATA);
532 		tpm_config_out(IOLIML, TPM_INF_ADDR);
533 		tpm_config_out((tpm_dev.data_regs & 0xff), TPM_INF_DATA);
534 
535 		/* control if IO-ports are set correctly */
536 		tpm_config_out(IOLIMH, TPM_INF_ADDR);
537 		ioh = tpm_config_in(TPM_INF_DATA);
538 		tpm_config_out(IOLIML, TPM_INF_ADDR);
539 		iol = tpm_config_in(TPM_INF_DATA);
540 
541 		if ((ioh << 8 | iol) != tpm_dev.data_regs) {
542 			dev_err(&dev->dev,
543 				"Could not set IO-data registers to 0x%x\n",
544 				tpm_dev.data_regs);
545 			rc = -EIO;
546 			goto err_release_region;
547 		}
548 
549 		/* activate register */
550 		tpm_config_out(TPM_DAR, TPM_INF_ADDR);
551 		tpm_config_out(0x01, TPM_INF_DATA);
552 		tpm_config_out(DISABLE_REGISTER_PAIR, TPM_INF_ADDR);
553 
554 		/* disable RESET, LP and IRQC */
555 		tpm_data_out(RESET_LP_IRQC_DISABLE, CMD);
556 
557 		/* Finally, we're done, print some infos */
558 		dev_info(&dev->dev, "TPM found: "
559 			 "config base 0x%lx, "
560 			 "data base 0x%lx, "
561 			 "chip version 0x%02x%02x, "
562 			 "vendor id 0x%x%x (Infineon), "
563 			 "product id 0x%02x%02x"
564 			 "%s\n",
565 			 tpm_dev.iotype == TPM_INF_IO_PORT ?
566 			 tpm_dev.config_port :
567 			 tpm_dev.map_base + tpm_dev.index_off,
568 			 tpm_dev.iotype == TPM_INF_IO_PORT ?
569 			 tpm_dev.data_regs :
570 			 tpm_dev.map_base + tpm_dev.data_regs,
571 			 version[0], version[1],
572 			 vendorid[0], vendorid[1],
573 			 productid[0], productid[1], chipname);
574 
575 		if (!(chip = tpm_register_hardware(&dev->dev, &tpm_inf)))
576 			goto err_release_region;
577 
578 		return 0;
579 	} else {
580 		rc = -ENODEV;
581 		goto err_release_region;
582 	}
583 
584 err_release_region:
585 	if (tpm_dev.iotype == TPM_INF_IO_PORT) {
586 		release_region(tpm_dev.data_regs, tpm_dev.data_size);
587 		release_region(tpm_dev.config_port, tpm_dev.config_size);
588 	} else {
589 		iounmap(tpm_dev.mem_base);
590 		release_mem_region(tpm_dev.map_base, tpm_dev.map_size);
591 	}
592 
593 err_last:
594 	return rc;
595 }
596 
597 static void tpm_inf_pnp_remove(struct pnp_dev *dev)
598 {
599 	struct tpm_chip *chip = pnp_get_drvdata(dev);
600 
601 	if (chip) {
602 		if (tpm_dev.iotype == TPM_INF_IO_PORT) {
603 			release_region(tpm_dev.data_regs, tpm_dev.data_size);
604 			release_region(tpm_dev.config_port,
605 				       tpm_dev.config_size);
606 		} else {
607 			iounmap(tpm_dev.mem_base);
608 			release_mem_region(tpm_dev.map_base, tpm_dev.map_size);
609 		}
610 		tpm_dev_vendor_release(chip);
611 		tpm_remove_hardware(chip->dev);
612 	}
613 }
614 
615 static int tpm_inf_pnp_suspend(struct pnp_dev *dev, pm_message_t pm_state)
616 {
617 	struct tpm_chip *chip = pnp_get_drvdata(dev);
618 	int rc;
619 	if (chip) {
620 		u8 savestate[] = {
621 			0, 193,	/* TPM_TAG_RQU_COMMAND */
622 			0, 0, 0, 10,	/* blob length (in bytes) */
623 			0, 0, 0, 152	/* TPM_ORD_SaveState */
624 		};
625 		dev_info(&dev->dev, "saving TPM state\n");
626 		rc = tpm_inf_send(chip, savestate, sizeof(savestate));
627 		if (rc < 0) {
628 			dev_err(&dev->dev, "error while saving TPM state\n");
629 			return rc;
630 		}
631 	}
632 	return 0;
633 }
634 
635 static int tpm_inf_pnp_resume(struct pnp_dev *dev)
636 {
637 	/* Re-configure TPM after suspending */
638 	tpm_config_out(ENABLE_REGISTER_PAIR, TPM_INF_ADDR);
639 	tpm_config_out(IOLIMH, TPM_INF_ADDR);
640 	tpm_config_out((tpm_dev.data_regs >> 8) & 0xff, TPM_INF_DATA);
641 	tpm_config_out(IOLIML, TPM_INF_ADDR);
642 	tpm_config_out((tpm_dev.data_regs & 0xff), TPM_INF_DATA);
643 	/* activate register */
644 	tpm_config_out(TPM_DAR, TPM_INF_ADDR);
645 	tpm_config_out(0x01, TPM_INF_DATA);
646 	tpm_config_out(DISABLE_REGISTER_PAIR, TPM_INF_ADDR);
647 	/* disable RESET, LP and IRQC */
648 	tpm_data_out(RESET_LP_IRQC_DISABLE, CMD);
649 	return tpm_pm_resume(&dev->dev);
650 }
651 
652 static struct pnp_driver tpm_inf_pnp_driver = {
653 	.name = "tpm_inf_pnp",
654 	.id_table = tpm_inf_pnp_tbl,
655 	.probe = tpm_inf_pnp_probe,
656 	.suspend = tpm_inf_pnp_suspend,
657 	.resume = tpm_inf_pnp_resume,
658 	.remove = tpm_inf_pnp_remove
659 };
660 
661 static int __init init_inf(void)
662 {
663 	return pnp_register_driver(&tpm_inf_pnp_driver);
664 }
665 
666 static void __exit cleanup_inf(void)
667 {
668 	pnp_unregister_driver(&tpm_inf_pnp_driver);
669 }
670 
671 module_init(init_inf);
672 module_exit(cleanup_inf);
673 
674 MODULE_AUTHOR("Marcel Selhorst <tpmdd@sirrix.com>");
675 MODULE_DESCRIPTION("Driver for Infineon TPM SLD 9630 TT 1.1 / SLB 9635 TT 1.2");
676 MODULE_VERSION("1.9.2");
677 MODULE_LICENSE("GPL");
678