• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /asuswrt-rt-n18u-9.0.0.4.380.2695/release/src-rt-6.x.4708/linux/linux-2.6/drivers/char/tpm/
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 <m.selhorst@sirrix.com>
8 * Sirrix AG - security technologies, http://www.sirrix.com and
9 * Applied Data Security Group, Ruhr-University Bochum, Germany
10 * Project-Homepage: http://www.prosec.rub.de/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
39struct 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
54static struct tpm_inf_dev tpm_dev;
55
56static 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
64static 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
72static 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
80static 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 */
89enum 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
107enum infineon_tpm_register {
108	WRFIFO = 0x00,
109	RDFIFO = 0x01,
110	STAT = 0x02,
111	CMD = 0x03
112};
113
114enum infineon_tpm_command_bits {
115	CMD_DIS = 0x00,
116	CMD_LP = 0x01,
117	CMD_RES = 0x02,
118	CMD_IRQC = 0x06
119};
120
121enum 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 */
131enum 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
146static int number_of_wtx;
147
148static 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
185static 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
206static 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
220static 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
232static 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
243static 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
250recv_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
313static 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
360static void tpm_inf_cancel(struct tpm_chip *chip)
361{
362}
363
364static u8 tpm_inf_status(struct tpm_chip *chip)
365{
366	return tpm_data_in(STAT);
367}
368
369static DEVICE_ATTR(pubek, S_IRUGO, tpm_show_pubek, NULL);
370static DEVICE_ATTR(pcrs, S_IRUGO, tpm_show_pcrs, NULL);
371static DEVICE_ATTR(caps, S_IRUGO, tpm_show_caps, NULL);
372static DEVICE_ATTR(cancel, S_IWUSR | S_IWGRP, NULL, tpm_store_cancel);
373
374static struct attribute *inf_attrs[] = {
375	&dev_attr_pubek.attr,
376	&dev_attr_pcrs.attr,
377	&dev_attr_caps.attr,
378	&dev_attr_cancel.attr,
379	NULL,
380};
381
382static struct attribute_group inf_attr_grp = {.attrs = inf_attrs };
383
384static const struct file_operations inf_ops = {
385	.owner = THIS_MODULE,
386	.llseek = no_llseek,
387	.open = tpm_open,
388	.read = tpm_read,
389	.write = tpm_write,
390	.release = tpm_release,
391};
392
393static const struct tpm_vendor_specific tpm_inf = {
394	.recv = tpm_inf_recv,
395	.send = tpm_inf_send,
396	.cancel = tpm_inf_cancel,
397	.status = tpm_inf_status,
398	.req_complete_mask = 0,
399	.req_complete_val = 0,
400	.attr_group = &inf_attr_grp,
401	.miscdev = {.fops = &inf_ops,},
402};
403
404static const struct pnp_device_id tpm_inf_pnp_tbl[] = {
405	/* Infineon TPMs */
406	{"IFX0101", 0},
407	{"IFX0102", 0},
408	{"", 0}
409};
410
411MODULE_DEVICE_TABLE(pnp, tpm_inf_pnp_tbl);
412
413static int __devinit tpm_inf_pnp_probe(struct pnp_dev *dev,
414				       const struct pnp_device_id *dev_id)
415{
416	int rc = 0;
417	u8 iol, ioh;
418	int vendorid[2];
419	int version[2];
420	int productid[2];
421	char chipname[20];
422	struct tpm_chip *chip;
423
424	/* read IO-ports through PnP */
425	if (pnp_port_valid(dev, 0) && pnp_port_valid(dev, 1) &&
426	    !(pnp_port_flags(dev, 0) & IORESOURCE_DISABLED)) {
427
428		tpm_dev.iotype = TPM_INF_IO_PORT;
429
430		tpm_dev.config_port = pnp_port_start(dev, 0);
431		tpm_dev.config_size = pnp_port_len(dev, 0);
432		tpm_dev.data_regs = pnp_port_start(dev, 1);
433		tpm_dev.data_size = pnp_port_len(dev, 1);
434		if ((tpm_dev.data_size < 4) || (tpm_dev.config_size < 2)) {
435			rc = -EINVAL;
436			goto err_last;
437		}
438		dev_info(&dev->dev, "Found %s with ID %s\n",
439			 dev->name, dev_id->id);
440		if (!((tpm_dev.data_regs >> 8) & 0xff)) {
441			rc = -EINVAL;
442			goto err_last;
443		}
444		/* publish my base address and request region */
445		if (request_region(tpm_dev.data_regs, tpm_dev.data_size,
446				   "tpm_infineon0") == NULL) {
447			rc = -EINVAL;
448			goto err_last;
449		}
450		if (request_region(tpm_dev.config_port, tpm_dev.config_size,
451				   "tpm_infineon0") == NULL) {
452			release_region(tpm_dev.data_regs, tpm_dev.data_size);
453			rc = -EINVAL;
454			goto err_last;
455		}
456	} else if (pnp_mem_valid(dev, 0) &&
457		   !(pnp_mem_flags(dev, 0) & IORESOURCE_DISABLED)) {
458
459		tpm_dev.iotype = TPM_INF_IO_MEM;
460
461		tpm_dev.map_base = pnp_mem_start(dev, 0);
462		tpm_dev.map_size = pnp_mem_len(dev, 0);
463
464		dev_info(&dev->dev, "Found %s with ID %s\n",
465			 dev->name, dev_id->id);
466
467		/* publish my base address and request region */
468		if (request_mem_region(tpm_dev.map_base, tpm_dev.map_size,
469				       "tpm_infineon0") == NULL) {
470			rc = -EINVAL;
471			goto err_last;
472		}
473
474		tpm_dev.mem_base = ioremap(tpm_dev.map_base, tpm_dev.map_size);
475		if (tpm_dev.mem_base == NULL) {
476			release_mem_region(tpm_dev.map_base, tpm_dev.map_size);
477			rc = -EINVAL;
478			goto err_last;
479		}
480
481		/*
482		 * The only known MMIO based Infineon TPM system provides
483		 * a single large mem region with the device config
484		 * registers at the default TPM_ADDR.  The data registers
485		 * seem like they could be placed anywhere within the MMIO
486		 * region, but lets just put them at zero offset.
487		 */
488		tpm_dev.index_off = TPM_ADDR;
489		tpm_dev.data_regs = 0x0;
490	} else {
491		rc = -EINVAL;
492		goto err_last;
493	}
494
495	/* query chip for its vendor, its version number a.s.o. */
496	tpm_config_out(ENABLE_REGISTER_PAIR, TPM_INF_ADDR);
497	tpm_config_out(IDVENL, TPM_INF_ADDR);
498	vendorid[1] = tpm_config_in(TPM_INF_DATA);
499	tpm_config_out(IDVENH, TPM_INF_ADDR);
500	vendorid[0] = tpm_config_in(TPM_INF_DATA);
501	tpm_config_out(IDPDL, TPM_INF_ADDR);
502	productid[1] = tpm_config_in(TPM_INF_DATA);
503	tpm_config_out(IDPDH, TPM_INF_ADDR);
504	productid[0] = tpm_config_in(TPM_INF_DATA);
505	tpm_config_out(CHIP_ID1, TPM_INF_ADDR);
506	version[1] = tpm_config_in(TPM_INF_DATA);
507	tpm_config_out(CHIP_ID2, TPM_INF_ADDR);
508	version[0] = tpm_config_in(TPM_INF_DATA);
509
510	switch ((productid[0] << 8) | productid[1]) {
511	case 6:
512		snprintf(chipname, sizeof(chipname), " (SLD 9630 TT 1.1)");
513		break;
514	case 11:
515		snprintf(chipname, sizeof(chipname), " (SLB 9635 TT 1.2)");
516		break;
517	default:
518		snprintf(chipname, sizeof(chipname), " (unknown chip)");
519		break;
520	}
521
522	if ((vendorid[0] << 8 | vendorid[1]) == (TPM_INFINEON_DEV_VEN_VALUE)) {
523
524		/* configure TPM with IO-ports */
525		tpm_config_out(IOLIMH, TPM_INF_ADDR);
526		tpm_config_out((tpm_dev.data_regs >> 8) & 0xff, TPM_INF_DATA);
527		tpm_config_out(IOLIML, TPM_INF_ADDR);
528		tpm_config_out((tpm_dev.data_regs & 0xff), TPM_INF_DATA);
529
530		/* control if IO-ports are set correctly */
531		tpm_config_out(IOLIMH, TPM_INF_ADDR);
532		ioh = tpm_config_in(TPM_INF_DATA);
533		tpm_config_out(IOLIML, TPM_INF_ADDR);
534		iol = tpm_config_in(TPM_INF_DATA);
535
536		if ((ioh << 8 | iol) != tpm_dev.data_regs) {
537			dev_err(&dev->dev,
538				"Could not set IO-data registers to 0x%x\n",
539				tpm_dev.data_regs);
540			rc = -EIO;
541			goto err_release_region;
542		}
543
544		/* activate register */
545		tpm_config_out(TPM_DAR, TPM_INF_ADDR);
546		tpm_config_out(0x01, TPM_INF_DATA);
547		tpm_config_out(DISABLE_REGISTER_PAIR, TPM_INF_ADDR);
548
549		/* disable RESET, LP and IRQC */
550		tpm_data_out(RESET_LP_IRQC_DISABLE, CMD);
551
552		/* Finally, we're done, print some infos */
553		dev_info(&dev->dev, "TPM found: "
554			 "config base 0x%lx, "
555			 "data base 0x%lx, "
556			 "chip version 0x%02x%02x, "
557			 "vendor id 0x%x%x (Infineon), "
558			 "product id 0x%02x%02x"
559			 "%s\n",
560			 tpm_dev.iotype == TPM_INF_IO_PORT ?
561			 tpm_dev.config_port :
562			 tpm_dev.map_base + tpm_dev.index_off,
563			 tpm_dev.iotype == TPM_INF_IO_PORT ?
564			 tpm_dev.data_regs :
565			 tpm_dev.map_base + tpm_dev.data_regs,
566			 version[0], version[1],
567			 vendorid[0], vendorid[1],
568			 productid[0], productid[1], chipname);
569
570		if (!(chip = tpm_register_hardware(&dev->dev, &tpm_inf)))
571			goto err_release_region;
572
573		return 0;
574	} else {
575		rc = -ENODEV;
576		goto err_release_region;
577	}
578
579err_release_region:
580	if (tpm_dev.iotype == TPM_INF_IO_PORT) {
581		release_region(tpm_dev.data_regs, tpm_dev.data_size);
582		release_region(tpm_dev.config_port, tpm_dev.config_size);
583	} else {
584		iounmap(tpm_dev.mem_base);
585		release_mem_region(tpm_dev.map_base, tpm_dev.map_size);
586	}
587
588err_last:
589	return rc;
590}
591
592static __devexit void tpm_inf_pnp_remove(struct pnp_dev *dev)
593{
594	struct tpm_chip *chip = pnp_get_drvdata(dev);
595
596	if (chip) {
597		if (tpm_dev.iotype == TPM_INF_IO_PORT) {
598			release_region(tpm_dev.data_regs, tpm_dev.data_size);
599			release_region(tpm_dev.config_port,
600				       tpm_dev.config_size);
601		} else {
602			iounmap(tpm_dev.mem_base);
603			release_mem_region(tpm_dev.map_base, tpm_dev.map_size);
604		}
605		tpm_dev_vendor_release(chip);
606		tpm_remove_hardware(chip->dev);
607	}
608}
609
610static int tpm_inf_pnp_suspend(struct pnp_dev *dev, pm_message_t pm_state)
611{
612	struct tpm_chip *chip = pnp_get_drvdata(dev);
613	int rc;
614	if (chip) {
615		u8 savestate[] = {
616			0, 193,	/* TPM_TAG_RQU_COMMAND */
617			0, 0, 0, 10,	/* blob length (in bytes) */
618			0, 0, 0, 152	/* TPM_ORD_SaveState */
619		};
620		dev_info(&dev->dev, "saving TPM state\n");
621		rc = tpm_inf_send(chip, savestate, sizeof(savestate));
622		if (rc < 0) {
623			dev_err(&dev->dev, "error while saving TPM state\n");
624			return rc;
625		}
626	}
627	return 0;
628}
629
630static int tpm_inf_pnp_resume(struct pnp_dev *dev)
631{
632	/* Re-configure TPM after suspending */
633	tpm_config_out(ENABLE_REGISTER_PAIR, TPM_INF_ADDR);
634	tpm_config_out(IOLIMH, TPM_INF_ADDR);
635	tpm_config_out((tpm_dev.data_regs >> 8) & 0xff, TPM_INF_DATA);
636	tpm_config_out(IOLIML, TPM_INF_ADDR);
637	tpm_config_out((tpm_dev.data_regs & 0xff), TPM_INF_DATA);
638	/* activate register */
639	tpm_config_out(TPM_DAR, TPM_INF_ADDR);
640	tpm_config_out(0x01, TPM_INF_DATA);
641	tpm_config_out(DISABLE_REGISTER_PAIR, TPM_INF_ADDR);
642	/* disable RESET, LP and IRQC */
643	tpm_data_out(RESET_LP_IRQC_DISABLE, CMD);
644	return tpm_pm_resume(&dev->dev);
645}
646
647static struct pnp_driver tpm_inf_pnp_driver = {
648	.name = "tpm_inf_pnp",
649	.id_table = tpm_inf_pnp_tbl,
650	.probe = tpm_inf_pnp_probe,
651	.suspend = tpm_inf_pnp_suspend,
652	.resume = tpm_inf_pnp_resume,
653	.remove = __devexit_p(tpm_inf_pnp_remove)
654};
655
656static int __init init_inf(void)
657{
658	return pnp_register_driver(&tpm_inf_pnp_driver);
659}
660
661static void __exit cleanup_inf(void)
662{
663	pnp_unregister_driver(&tpm_inf_pnp_driver);
664}
665
666module_init(init_inf);
667module_exit(cleanup_inf);
668
669MODULE_AUTHOR("Marcel Selhorst <m.selhorst@sirrix.com>");
670MODULE_DESCRIPTION("Driver for Infineon TPM SLD 9630 TT 1.1 / SLB 9635 TT 1.2");
671MODULE_VERSION("1.9.2");
672MODULE_LICENSE("GPL");
673