Merge tag 'rust-fixes-6.12' of https://github.com/Rust-for-Linux/linux
[linux-block.git] / drivers / char / tpm / tpm_infineon.c
CommitLineData
b886d83c 1// SPDX-License-Identifier: GPL-2.0-only
ebb81fdb
MS
2/*
3 * Description:
4 * Device Driver for the Infineon Technologies
f9abb020 5 * SLD 9630 TT 1.1 and SLB 9635 TT 1.2 Trusted Platform Module
ebb81fdb
MS
6 * Specifications at www.trustedcomputinggroup.org
7 *
cbb2d5e4
RA
8 * Copyright (C) 2005, Marcel Selhorst <tpmdd@selhorst.net>
9 * Sirrix AG - security technologies <tpmdd@sirrix.com> and
ebb81fdb 10 * Applied Data Security Group, Ruhr-University Bochum, Germany
631dd1a8 11 * Project-Homepage: http://www.trust.rub.de/projects/linux-device-driver-infineon-tpm/
ebb81fdb
MS
12 */
13
397c7182 14#include <linux/init.h>
f9abb020 15#include <linux/pnp.h>
ebb81fdb
MS
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
f9abb020
MS
27#define TPM_INFINEON_DEV_VEN_VALUE 0x15D1
28
d954e8ed
AW
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
35struct tpm_inf_dev {
36 int iotype;
37
93716b94
MS
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 */
d954e8ed 42
93716b94 43 unsigned int data_regs; /* Data registers */
d954e8ed
AW
44 unsigned int data_size;
45
46 unsigned int config_port; /* IO Port config index reg */
47 unsigned int config_size;
48};
49
50static struct tpm_inf_dev tpm_dev;
51
52static inline void tpm_data_out(unsigned char data, unsigned char offset)
53{
61551536 54#ifdef CONFIG_HAS_IOPORT
d954e8ed
AW
55 if (tpm_dev.iotype == TPM_INF_IO_PORT)
56 outb(data, tpm_dev.data_regs + offset);
57 else
61551536 58#endif
d954e8ed
AW
59 writeb(data, tpm_dev.mem_base + tpm_dev.data_regs + offset);
60}
61
62static inline unsigned char tpm_data_in(unsigned char offset)
63{
61551536 64#ifdef CONFIG_HAS_IOPORT
d954e8ed
AW
65 if (tpm_dev.iotype == TPM_INF_IO_PORT)
66 return inb(tpm_dev.data_regs + offset);
61551536
NS
67#endif
68 return readb(tpm_dev.mem_base + tpm_dev.data_regs + offset);
d954e8ed
AW
69}
70
71static inline void tpm_config_out(unsigned char data, unsigned char offset)
72{
61551536 73#ifdef CONFIG_HAS_IOPORT
d954e8ed
AW
74 if (tpm_dev.iotype == TPM_INF_IO_PORT)
75 outb(data, tpm_dev.config_port + offset);
76 else
61551536 77#endif
d954e8ed
AW
78 writeb(data, tpm_dev.mem_base + tpm_dev.index_off + offset);
79}
80
81static inline unsigned char tpm_config_in(unsigned char offset)
82{
61551536 83#ifdef CONFIG_HAS_IOPORT
d954e8ed
AW
84 if (tpm_dev.iotype == TPM_INF_IO_PORT)
85 return inb(tpm_dev.config_port + offset);
61551536
NS
86#endif
87 return readb(tpm_dev.mem_base + tpm_dev.index_off + offset);
d954e8ed 88}
ebb81fdb
MS
89
90/* TPM header definitions */
91enum 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
109enum infineon_tpm_register {
110 WRFIFO = 0x00,
111 RDFIFO = 0x01,
112 STAT = 0x02,
113 CMD = 0x03
114};
115
116enum infineon_tpm_command_bits {
117 CMD_DIS = 0x00,
118 CMD_LP = 0x01,
119 CMD_RES = 0x02,
120 CMD_IRQC = 0x06
121};
122
123enum 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 */
133enum infineon_tpm_values {
134 CHIP_ID1 = 0x20,
135 CHIP_ID2 = 0x21,
3dcce8e2 136 TPM_DAR = 0x30,
ebb81fdb
MS
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
148static int number_of_wtx;
149
150static 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++) {
d954e8ed 158 status = tpm_data_in(WRFIFO);
ebb81fdb
MS
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 {
d954e8ed
AW
178 status = tpm_data_in(RDFIFO);
179 status = tpm_data_in(STAT);
ebb81fdb
MS
180 i++;
181 if (i == TPM_MAX_TRIES)
182 return -EIO;
183 } while ((status & (1 << STAT_RDA)) != 0);
184 return 0;
185}
186
187static 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++) {
d954e8ed 192 status = tpm_data_in(STAT);
ebb81fdb
MS
193 /* check the status-register if wait_for_bit is set */
194 if (status & 1 << wait_for_bit)
195 break;
9f3fc7bc 196 tpm_msleep(TPM_MSLEEP_TIME);
ebb81fdb
MS
197 }
198 if (i == TPM_MAX_TRIES) { /* timeout occurs */
199 if (wait_for_bit == STAT_XFE)
8cfffc9d 200 dev_err(&chip->dev, "Timeout in wait(STAT_XFE)\n");
ebb81fdb 201 if (wait_for_bit == STAT_RDA)
8cfffc9d 202 dev_err(&chip->dev, "Timeout in wait(STAT_RDA)\n");
ebb81fdb
MS
203 return -EIO;
204 }
205 return 0;
206};
207
208static void wait_and_send(struct tpm_chip *chip, u8 sendbyte)
209{
210 wait(chip, STAT_XFE);
d954e8ed 211 tpm_data_out(sendbyte, WRFIFO);
ebb81fdb
MS
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
222static void tpm_wtx(struct tpm_chip *chip)
223{
224 number_of_wtx++;
8cfffc9d 225 dev_info(&chip->dev, "Granting WTX (%02d / %02d)\n",
ebb81fdb
MS
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);
9f3fc7bc 231 tpm_msleep(TPM_WTX_MSLEEP_TIME);
ebb81fdb
MS
232}
233
234static void tpm_wtx_abort(struct tpm_chip *chip)
235{
8cfffc9d 236 dev_info(&chip->dev, "Aborting WTX\n");
ebb81fdb
MS
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;
9f3fc7bc 242 tpm_msleep(TPM_WTX_MSLEEP_TIME);
ebb81fdb
MS
243}
244
245static int tpm_inf_recv(struct tpm_chip *chip, u8 * buf, size_t count)
246{
247 int i;
248 int ret;
249 u32 size = 0;
8c9e8779 250 number_of_wtx = 0;
ebb81fdb
MS
251
252recv_begin:
253 /* start receiving header */
254 for (i = 0; i < 4; i++) {
255 ret = wait(chip, STAT_RDA);
256 if (ret)
257 return -EIO;
d954e8ed 258 buf[i] = tpm_data_in(RDFIFO);
ebb81fdb
MS
259 }
260
261 if (buf[0] != TPM_VL_VER) {
8cfffc9d 262 dev_err(&chip->dev,
ebb81fdb
MS
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);
d954e8ed 273 buf[i] = tpm_data_in(RDFIFO);
ebb81fdb
MS
274 }
275
276 if ((size == 0x6D00) && (buf[1] == 0x80)) {
8cfffc9d 277 dev_err(&chip->dev, "Error handling on vendor layer!\n");
ebb81fdb
MS
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) {
8cfffc9d 289 dev_info(&chip->dev, "WTX-package received\n");
ebb81fdb
MS
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) {
8cfffc9d 300 dev_info(&chip->dev, "WTX-abort acknowledged\n");
ebb81fdb
MS
301 return size;
302 }
303
304 if (buf[1] == TPM_CTRL_ERROR) {
8cfffc9d 305 dev_err(&chip->dev, "ERROR-package received:\n");
ebb81fdb 306 if (buf[4] == TPM_INF_NAK)
8cfffc9d 307 dev_err(&chip->dev,
ebb81fdb
MS
308 "-> Negative acknowledgement"
309 " - retransmit command!\n");
310 return -EIO;
311 }
312 return -EIO;
313}
314
315static 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 */
d954e8ed 322 tpm_data_out(RESET_LP_IRQC_DISABLE, CMD);
ebb81fdb
MS
323
324 ret = empty_fifo(chip, 1);
325 if (ret) {
8cfffc9d 326 dev_err(&chip->dev, "Timeout while clearing FIFO\n");
ebb81fdb
MS
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 }
f5595f5b 359 return 0;
ebb81fdb
MS
360}
361
362static void tpm_inf_cancel(struct tpm_chip *chip)
363{
f9abb020
MS
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.
ebb81fdb
MS
368 */
369}
370
b4ed3e3c
KJH
371static u8 tpm_inf_status(struct tpm_chip *chip)
372{
d954e8ed 373 return tpm_data_in(STAT);
b4ed3e3c
KJH
374}
375
01ad1fa7 376static const struct tpm_class_ops tpm_inf = {
ebb81fdb
MS
377 .recv = tpm_inf_recv,
378 .send = tpm_inf_send,
379 .cancel = tpm_inf_cancel,
b4ed3e3c 380 .status = tpm_inf_status,
ebb81fdb
MS
381 .req_complete_mask = 0,
382 .req_complete_val = 0,
ebb81fdb
MS
383};
384
93716b94 385static const struct pnp_device_id tpm_inf_pnp_tbl[] = {
f9abb020
MS
386 /* Infineon TPMs */
387 {"IFX0101", 0},
388 {"IFX0102", 0},
389 {"", 0}
390};
1b8333b0 391
93716b94 392MODULE_DEVICE_TABLE(pnp, tpm_inf_pnp_tbl);
f9abb020 393
afc6d369 394static int tpm_inf_pnp_probe(struct pnp_dev *dev,
1b8333b0 395 const struct pnp_device_id *dev_id)
ebb81fdb
MS
396{
397 int rc = 0;
398 u8 iol, ioh;
399 int vendorid[2];
400 int version[2];
401 int productid[2];
30bbafe3 402 const char *chipname;
e496f540 403 struct tpm_chip *chip;
ebb81fdb 404
1b8333b0
MS
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)) {
d954e8ed 408
93716b94 409 tpm_dev.iotype = TPM_INF_IO_PORT;
d954e8ed
AW
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)) {
8c9e8779
MS
416 rc = -EINVAL;
417 goto err_last;
418 }
1b8333b0
MS
419 dev_info(&dev->dev, "Found %s with ID %s\n",
420 dev->name, dev_id->id);
d954e8ed 421 if (!((tpm_dev.data_regs >> 8) & 0xff)) {
8c9e8779
MS
422 rc = -EINVAL;
423 goto err_last;
424 }
1b8333b0 425 /* publish my base address and request region */
d954e8ed
AW
426 if (request_region(tpm_dev.data_regs, tpm_dev.data_size,
427 "tpm_infineon0") == NULL) {
8c9e8779
MS
428 rc = -EINVAL;
429 goto err_last;
430 }
d954e8ed
AW
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);
8c9e8779
MS
434 rc = -EINVAL;
435 goto err_last;
1b8333b0 436 }
d954e8ed 437 } else if (pnp_mem_valid(dev, 0) &&
93716b94 438 !(pnp_mem_flags(dev, 0) & IORESOURCE_DISABLED)) {
d954e8ed 439
93716b94 440 tpm_dev.iotype = TPM_INF_IO_MEM;
d954e8ed
AW
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;
e8a65015 471 } else {
8c9e8779
MS
472 rc = -EINVAL;
473 goto err_last;
f9abb020
MS
474 }
475
ebb81fdb 476 /* query chip for its vendor, its version number a.s.o. */
d954e8ed
AW
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);
f9abb020
MS
490
491 switch ((productid[0] << 8) | productid[1]) {
492 case 6:
30bbafe3 493 chipname = " (SLD 9630 TT 1.1)";
f9abb020
MS
494 break;
495 case 11:
30bbafe3 496 chipname = " (SLB 9635 TT 1.2)";
f9abb020
MS
497 break;
498 default:
30bbafe3 499 chipname = " (unknown chip)";
f9abb020
MS
500 break;
501 }
f9abb020
MS
502
503 if ((vendorid[0] << 8 | vendorid[1]) == (TPM_INFINEON_DEV_VEN_VALUE)) {
ebb81fdb 504
f9abb020 505 /* configure TPM with IO-ports */
d954e8ed
AW
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);
f9abb020
MS
510
511 /* control if IO-ports are set correctly */
d954e8ed
AW
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);
f9abb020 516
d954e8ed 517 if ((ioh << 8 | iol) != tpm_dev.data_regs) {
1b8333b0 518 dev_err(&dev->dev,
d954e8ed
AW
519 "Could not set IO-data registers to 0x%x\n",
520 tpm_dev.data_regs);
8c9e8779
MS
521 rc = -EIO;
522 goto err_release_region;
ebb81fdb
MS
523 }
524
525 /* activate register */
d954e8ed
AW
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);
ebb81fdb
MS
529
530 /* disable RESET, LP and IRQC */
d954e8ed 531 tpm_data_out(RESET_LP_IRQC_DISABLE, CMD);
ebb81fdb
MS
532
533 /* Finally, we're done, print some infos */
1b8333b0 534 dev_info(&dev->dev, "TPM found: "
d954e8ed
AW
535 "config base 0x%lx, "
536 "data base 0x%lx, "
e496f540
MS
537 "chip version 0x%02x%02x, "
538 "vendor id 0x%x%x (Infineon), "
539 "product id 0x%02x%02x"
ebb81fdb 540 "%s\n",
d954e8ed 541 tpm_dev.iotype == TPM_INF_IO_PORT ?
93716b94
MS
542 tpm_dev.config_port :
543 tpm_dev.map_base + tpm_dev.index_off,
d954e8ed 544 tpm_dev.iotype == TPM_INF_IO_PORT ?
93716b94
MS
545 tpm_dev.data_regs :
546 tpm_dev.map_base + tpm_dev.data_regs,
ebb81fdb
MS
547 version[0], version[1],
548 vendorid[0], vendorid[1],
f9abb020 549 productid[0], productid[1], chipname);
ebb81fdb 550
afb5abc2
JS
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)
8c9e8779 559 goto err_release_region;
d954e8ed 560
ebb81fdb
MS
561 return 0;
562 } else {
8c9e8779
MS
563 rc = -ENODEV;
564 goto err_release_region;
ebb81fdb 565 }
8c9e8779
MS
566
567err_release_region:
d954e8ed
AW
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 }
8c9e8779
MS
575
576err_last:
577 return rc;
ebb81fdb
MS
578}
579
39af33fc 580static void tpm_inf_pnp_remove(struct pnp_dev *dev)
e659a3fe 581{
1b8333b0 582 struct tpm_chip *chip = pnp_get_drvdata(dev);
e659a3fe 583
afb5abc2
JS
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);
1b8333b0 593 }
e659a3fe
KJH
594}
595
6b37729b
PH
596#ifdef CONFIG_PM_SLEEP
597static int tpm_inf_resume(struct device *dev)
93716b94
MS
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);
6b37729b 611 return tpm_pm_resume(dev);
93716b94 612}
6b37729b
PH
613#endif
614static SIMPLE_DEV_PM_OPS(tpm_inf_pm, tpm_pm_suspend, tpm_inf_resume);
93716b94 615
e1d42c98 616static struct pnp_driver tpm_inf_pnp_driver = {
1b8333b0 617 .name = "tpm_inf_pnp",
93716b94 618 .id_table = tpm_inf_pnp_tbl,
1b8333b0 619 .probe = tpm_inf_pnp_probe,
6b37729b
PH
620 .remove = tpm_inf_pnp_remove,
621 .driver = {
622 .pm = &tpm_inf_pm,
623 }
ebb81fdb
MS
624};
625
15516603 626module_pnp_driver(tpm_inf_pnp_driver);
ebb81fdb 627
cbb2d5e4 628MODULE_AUTHOR("Marcel Selhorst <tpmdd@sirrix.com>");
f9abb020 629MODULE_DESCRIPTION("Driver for Infineon TPM SLD 9630 TT 1.1 / SLB 9635 TT 1.2");
93716b94 630MODULE_VERSION("1.9.2");
ebb81fdb 631MODULE_LICENSE("GPL");